{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Deep Q-Network implementation (TensorFlow).\n",
    "\n",
    "In this notebook, we will implement DQN with **experience replay** and **target networks**.\n",
    "\n",
    "$$ \n",
    "\\DeclareMathOperator*{\\max}{max}$$\n",
    "\n",
    "Q Learning control is carried out by sampling step by step and updating Q values at each step. We use ε-greedy policy to explore and generate samples. However, the policy learnt is a deterministic greedy policy with no exploration. We can carryout updates online i.e. we take a step and use `(current state, action, reward and next_state)` tuple to update. \n",
    "\n",
    "In case of function approximation using neural network, the input to the network is the state and output is the q(s,a) for all the actions in the state `s`. It is denoted as $ \\hat{q}(s_t,a; w_{t}) $, where $w_{t}$ is the weigths of the neural network which we are trying to learn as part of DQN learning. \n",
    "\n",
    "We use two networks, one target network to get the max q-value of next state denoted by $ \\max_a \\hat {q}(s_{t+1},a; w^{-}_{t}) $ and the primary network with weights $w_{t}$ which we are updated based on back propagation of the TD error through the network.\n",
    "\n",
    "The Update equation is given below. This is the online version:\n",
    "$$ w_{t+1} \\leftarrow w_t + \\alpha [ R_{t+1} + \\gamma . \\max_{a} \\hat{q}(S_{t+1},a,w^{-}_{t}) – \\hat{q}(S_t,A_t,w_t)] \\nabla \\hat{q}(S_t,A_t,w_t)$$\n",
    "\n",
    "Online update with neural network with millions of weights does not work well. Accordingly, We use experience replay (aka Replay Buffer).  We use a behavior policy to explore the environment and store the samples `(s, a, r, s', done)` in a buffer. The samples are generated using an exploratory behavior policy while we improve a deterministic target policy using q-values. \n",
    "\n",
    "Therefore, we can always use older samples from behavior policy and apply them again and again. We can keep the buffer size fixed to some pre-determined size and keep deleting the older samples as we collect new ones. This process makes learning sample efficient by reusing a sample multiple times and also removing temporal dependence of the samples we would otherwise see while following a trajectory.\n",
    "\n",
    "The update equation with batch update with minor modifications is given below. We collect samples of transitions (current state, action, reward, next state) in a buffer. Where each sample is denoted as a tuple: \n",
    "\n",
    "$$ (s_{i}, a_{i}, r_{i}, s^{'}_{i}, done_{i})$$\n",
    "\n",
    "Subscript (i) denotes ith sample. We take N samples from experience replay selecting randomly and update the weights. Subscript (t) denotes the index of weight updates. If the current state is done, as denoted by `done` flag, the target is just the reward as terminal states have zero value. The final update equation is as given below:\n",
    "\n",
    "$$w_{t+1} \\leftarrow w_t + \\alpha \\frac{1}{N} \\sum_{i=1}^{N} \\left[ r_i + \\left( (1-done_i) . \\gamma .  \\max_{a^{'}} \\hat{q}(s_{i}^{'},a^{'};w^{-}_{t}) \\right) – \\hat{q}(s_i,a_i;w_t) \\right] \\nabla \\hat{q}(s_i,a_i;w_t)$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import random\n",
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "from tensorflow.keras.layers import Dense, Flatten\n",
    "from tensorflow.keras import Model\n",
    "import gym\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from scipy.signal import convolve, gaussian\n",
    "\n",
    "import os\n",
    "import io\n",
    "import base64\n",
    "import time\n",
    "import glob\n",
    "from IPython.display import HTML\n",
    "\n",
    "%matplotlib inline\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Environment - CartPole \n",
    "\n",
    "We can use the setup here to run on any environment which has state as a single vector and actions are discrete. We will build it on Cart Pole and they try to run this on many other environments like Atari games and others."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "def make_env(env_name, seed=None):\n",
    "    # remove time limit wrapper from environment\n",
    "    env = gym.make(env_name).unwrapped\n",
    "    if seed is not None:\n",
    "        env.seed(seed)\n",
    "    return env"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "env_name = 'CartPole-v1'\n",
    "\n",
    "env = make_env(env_name)\n",
    "env.reset()\n",
    "plt.imshow(env.render(\"rgb_array\"))\n",
    "state_shape, n_actions = env.observation_space.shape, env.action_space.n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Building a network using tensorflow"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let us build a DQN agent using a simple network. We now need to build a neural network that can map states/observations to state q-values. The observation space and action space is as given below for CartPole\n",
    "\n",
    "    Observation:\n",
    "        Type: Box(4)\n",
    "        Num     Observation               Min                     Max\n",
    "        0       Cart Position             -4.8                    4.8\n",
    "        1       Cart Velocity             -Inf                    Inf\n",
    "        2       Pole Angle                -0.418 rad (-24 deg)    0.418 rad (24 deg)\n",
    "        3       Pole Angular Velocity     -Inf                    Inf\n",
    "    Actions:\n",
    "        Type: Discrete(2)\n",
    "        Num   Action\n",
    "        0     Push cart to the left\n",
    "        1     Push cart to the right\n",
    "        \n",
    "\n",
    "The model will be a simple one with 2 hidden layers with Relu activation and final layer being logits with dimension equal to number of actions. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "class DQNAgent:\n",
    "    def __init__(self, state_shape, n_actions, epsilon=0):\n",
    "        self.epsilon = epsilon\n",
    "        self.n_actions = n_actions\n",
    "        self.state_shape = state_shape\n",
    "\n",
    "        state_dim = state_shape[0]\n",
    "        self.model = tf.keras.models.Sequential()\n",
    "        self.model.add(tf.keras.Input(shape=(state_dim,)))\n",
    "        self.model.add(tf.keras.layers.Dense(192, activation='relu'))\n",
    "        self.model.add(tf.keras.layers.Dense(256, activation='relu'))\n",
    "        self.model.add(tf.keras.layers.Dense(64, activation='relu'))\n",
    "        self.model.add(tf.keras.layers.Dense(n_actions))\n",
    "    \n",
    "    def __call__(self, state_t):\n",
    "        # pass the state at time t through the newrok to get Q(s,a)\n",
    "        qvalues = self.model(state_t)\n",
    "        return qvalues\n",
    "\n",
    "    def get_qvalues(self, states):\n",
    "        # input is an array of states in numpy and outout is Qvals as numpy array\n",
    "        qvalues = self.model(states)\n",
    "        return qvalues.numpy()\n",
    "\n",
    "    def sample_actions(self, qvalues):\n",
    "        # sample actions from a batch of q_values using epsilon greedy policy\n",
    "        epsilon = self.epsilon\n",
    "        batch_size, n_actions = qvalues.shape\n",
    "        random_actions = np.random.choice(n_actions, size=batch_size)\n",
    "        best_actions = qvalues.argmax(axis=-1)\n",
    "        should_explore = np.random.choice(\n",
    "            [0, 1], batch_size, p=[1-epsilon, epsilon])\n",
    "        return np.where(should_explore, random_actions, best_actions)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "agent = DQNAgent(state_shape, n_actions, epsilon=0.5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"sequential\"\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "dense (Dense)                (None, 192)               960       \n",
      "_________________________________________________________________\n",
      "dense_1 (Dense)              (None, 256)               49408     \n",
      "_________________________________________________________________\n",
      "dense_2 (Dense)              (None, 64)                16448     \n",
      "_________________________________________________________________\n",
      "dense_3 (Dense)              (None, 2)                 130       \n",
      "=================================================================\n",
      "Total params: 66,946\n",
      "Trainable params: 66,946\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "agent.model.summary()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "def evaluate(env, agent, n_games=1, greedy=False, t_max=10000):\n",
    "    rewards = []\n",
    "    for _ in range(n_games):\n",
    "        s = env.reset()\n",
    "        reward = 0\n",
    "        for _ in range(t_max):\n",
    "            qvalues = agent.get_qvalues(np.array([s]))\n",
    "            action = qvalues.argmax(axis=-1)[0] if greedy else agent.sample_actions(qvalues)[0]\n",
    "            s, r, done, _ = env.step(action)\n",
    "            reward += r\n",
    "            if done:\n",
    "                break\n",
    "\n",
    "        rewards.append(reward)\n",
    "    return np.mean(rewards)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "36.0"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "evaluate(env, agent, n_games=1)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "env.close()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Experience replay\n",
    "\n",
    "We will use the replay buffer we saw in chapter 4 listings. Replay buffer is very important in DQN to break the correlation between samples. We use a behavior policy ($\\epsilon-greedy$) to sample from the environment and store the transitions (s,a,r,s',done) into a buffer. These samples are used multiple times in a learning making the process sample efficient. \n",
    "\n",
    "The interface to ReplayBuffer is:\n",
    "* `exp_replay.add(state, action, reward, next_state, done)` - saves (s,a,r,s',done) tuple into the buffer\n",
    "* `exp_replay.sample(batch_size)` - returns states, actions, rewards, next_states and done_flags for `batch_size` random samples.\n",
    "* `len(exp_replay)` - returns number of elements stored in replay buffer.\n",
    "\n",
    "We have modified the implementation a bit to make it more efficient"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "class ReplayBuffer:\n",
    "    def __init__(self, size):\n",
    "        self.size = size #max number of items in buffer\n",
    "        self.buffer =[] #array to holde buffer\n",
    "        self.next_id = 0\n",
    "    \n",
    "    def __len__(self):\n",
    "        return len(self.buffer)\n",
    "    \n",
    "    def add(self, state, action, reward, next_state, done):\n",
    "        item = (state, action, reward, next_state, done)\n",
    "        if len(self.buffer) < self.size:\n",
    "           self.buffer.append(item)\n",
    "        else:\n",
    "            self.buffer[self.next_id] = item\n",
    "        self.next_id = (self.next_id + 1) % self.size\n",
    "        \n",
    "    def sample(self, batch_size):\n",
    "        idxs = np.random.choice(len(self.buffer), batch_size)\n",
    "        samples = [self.buffer[i] for i in idxs]\n",
    "        states, actions, rewards, next_states, done_flags = list(zip(*samples))\n",
    "        return np.array(states), np.array(actions), np.array(rewards), np.array(next_states), np.array(done_flags)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "def play_and_record(start_state, agent, env, exp_replay, n_steps=1):\n",
    "\n",
    "    s = start_state\n",
    "    sum_rewards = 0\n",
    "\n",
    "    # Play the game for n_steps and record transitions in buffer\n",
    "    for _ in range(n_steps):\n",
    "        qvalues = agent.get_qvalues(np.array([s]))\n",
    "        a = agent.sample_actions(qvalues)[0]        \n",
    "        next_s, r, done, _ = env.step(a)\n",
    "        sum_rewards += r\n",
    "        exp_replay.add(s, a, r, next_s, done)\n",
    "        if done:\n",
    "            s = env.reset()\n",
    "        else:\n",
    "            s = next_s\n",
    "        \n",
    "    return sum_rewards, s"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Target network\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "target_network = DQNAgent(agent.state_shape, agent.n_actions, epsilon=0.5)\n",
    "target_network.model.set_weights(agent.model.get_weights())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Learning with... Q-learning\n",
    "Here we write a function similar to tabular q-learning. We will calculate average TD error per batch using the equation: \n",
    "\n",
    "$$ L =  \\frac{1}{N} \\sum_{i=1}^{N} \\left[ r_i + \\left( (1-done_i) . \\gamma .  \\max_{a^{'}} \\hat{q}(s_{i}^{'},a^{'};w^{-}_{t}) \\right) – \\hat{q}(s_i,a_i;w_t) \\right]^2$$\n",
    "\n",
    "\n",
    "$$ \\nabla_w L =   - \\frac{1}{N} \\sum_{i=1}^{N} \\left[ r_i + \\left( (1-done_i) . \\gamma .  \\max_{a^{'}} \\hat{q}(s_{i}^{'},a^{'};w^{-}_{t}) \\right) – \\hat{q}(s_i,a_i;w_t) \\right] \\nabla \\hat{q}(s_i,a_i;w_t)$$\n",
    "\n",
    "\n",
    "$\\hat{q}(s',A;w^{-})$ is calculated using target network whose weights are held constant and refreshed periodically from the agent learning network. \n",
    "\n",
    "Target is given by following:\n",
    "* non terminal state: $r_i +  \\gamma .  \\max_{a^{'}} \\hat{q}(s_{i}^{'},a^{'};w^{-}_{t})$\n",
    "* terminal state: $ r_i $\n",
    "\n",
    "We then carryout back propagation through the agent network to update the weights using equation below:\n",
    "\n",
    "\n",
    "$$ \n",
    "\\DeclareMathOperator*{\\max}{max} w_{t+1} \\leftarrow w_t - \\alpha \\nabla_{w}L$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "def compute_td_loss(agent, target_network, states, actions, rewards, next_states, done_flags,\n",
    "                    gamma=0.99):\n",
    "\n",
    "    # get q-values for all actions in current states\n",
    "    # use agent network\n",
    "    predicted_qvalues = agent(states)\n",
    "\n",
    "    # compute q-values for all actions in next states\n",
    "    # use target network\n",
    "    predicted_next_qvalues = target_network(next_states)\n",
    "    \n",
    "    # select q-values for chosen actions\n",
    "    row_indices= tf.range(len(actions))\n",
    "    indices = tf.transpose([row_indices, actions])\n",
    "    predicted_qvalues_for_actions = tf.gather_nd(predicted_qvalues, indices)\n",
    "    \n",
    "\n",
    "    # compute Qmax(next_states, actions) using predicted next q-values\n",
    "    next_state_values = tf.reduce_max(predicted_next_qvalues, axis=1)\n",
    "\n",
    "    # compute \"target q-values\" \n",
    "    target_qvalues_for_actions = rewards + gamma * next_state_values * (1-done_flags)\n",
    "\n",
    "    # mean squared error loss to minimize\n",
    "    loss = tf.keras.losses.MSE(target_qvalues_for_actions, predicted_qvalues_for_actions)\n",
    "\n",
    "    return loss"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Main loop\n",
    "\n",
    "We now carryout the training on DQN setup above."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "from tqdm import trange\n",
    "from IPython.display import clear_output\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "# set a seed\n",
    "seed = 13\n",
    "random.seed(seed)\n",
    "np.random.seed(seed)\n",
    "tf.random.set_seed(seed)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "#setup env and agent and target networks\n",
    "env_name = 'CartPole-v1'\n",
    "env = make_env(env_name, seed)\n",
    "state_dim = env.observation_space.shape\n",
    "n_actions = env.action_space.n\n",
    "state = env.reset()\n",
    "\n",
    "agent = DQNAgent(state_dim, n_actions, epsilon=1)\n",
    "target_network = DQNAgent(state_dim, n_actions, epsilon=1)\n",
    "target_network.model.set_weights(agent.model.get_weights())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "10000\n"
     ]
    }
   ],
   "source": [
    "# let us fill experience replay with some samples using full random policy\n",
    "exp_replay = ReplayBuffer(10**4)\n",
    "for i in range(100):\n",
    "    play_and_record(state, agent, env, exp_replay, n_steps=10**2)\n",
    "    if len(exp_replay) == 10**4:\n",
    "        break\n",
    "print(len(exp_replay))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "#setup some parameters for training\n",
    "timesteps_per_epoch = 1\n",
    "batch_size = 32\n",
    "total_steps = 5 * 10**4\n",
    "\n",
    "#init Optimizer\n",
    "optimizer = tf.keras.optimizers.Adam(learning_rate=1e-4)\n",
    "# set exploration epsilon \n",
    "start_epsilon = 1\n",
    "end_epsilon = 0.05\n",
    "eps_decay_final_step = 2 * 10**4\n",
    "\n",
    "# setup spme frequency for loggind and updating target network\n",
    "loss_freq = 20\n",
    "refresh_target_network_freq = 100\n",
    "eval_freq = 1000\n",
    "\n",
    "# to clip the gradients\n",
    "max_grad_norm = 5000"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "mean_rw_history = []\n",
    "td_loss_history = []\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "def epsilon_schedule(start_eps, end_eps, step, final_step):\n",
    "    return start_eps + (end_eps-start_eps)*min(step, final_step)/final_step\n",
    "\n",
    "def smoothen(values):\n",
    "    kernel = gaussian(100, std=100)\n",
    "    kernel = kernel / np.sum(kernel)\n",
    "    return convolve(values, kernel, 'valid')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "buffer size = 10000, epsilon = 0.05000\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 1152x360 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|████████████████████████████████████████████████████████████████████████████| 50001/50001 [08:51<00:00, 94.13it/s]\n"
     ]
    }
   ],
   "source": [
    "state = env.reset()\n",
    "for step in trange(total_steps + 1):\n",
    "    \n",
    "    # reduce exploration as we progress\n",
    "    agent.epsilon = epsilon_schedule(start_epsilon, end_epsilon, step, eps_decay_final_step)\n",
    "\n",
    "    # take timesteps_per_epoch and update experience replay buffer\n",
    "    _, state = play_and_record(state, agent, env, exp_replay, timesteps_per_epoch)\n",
    "\n",
    "    # train by sampling batch_size of data from experience replay\n",
    "    states, actions, rewards, next_states, done_flags = exp_replay.sample(batch_size)\n",
    "    \n",
    "    with tf.GradientTape() as tape:\n",
    "        # loss = <compute TD loss>\n",
    "        loss = compute_td_loss(agent, target_network, \n",
    "                               states, actions, rewards, next_states, done_flags,                  \n",
    "                               gamma=0.99)\n",
    "\n",
    "    gradients = tape.gradient(loss, agent.model.trainable_variables)\n",
    "    clipped_grads = [tf.clip_by_norm(g, max_grad_norm) for g in gradients]\n",
    "    optimizer.apply_gradients(zip(clipped_grads, agent.model.trainable_variables))\n",
    "\n",
    "\n",
    "    if step % loss_freq == 0:\n",
    "        td_loss_history.append(loss.numpy())\n",
    "\n",
    "    if step % refresh_target_network_freq == 0:\n",
    "        # Load agent weights into target_network\n",
    "        target_network.model.set_weights(agent.model.get_weights())\n",
    "\n",
    "    if step % eval_freq == 0:\n",
    "        # eval the agent\n",
    "        mean_rw_history.append(evaluate(\n",
    "            make_env(env_name, seed=step), agent, n_games=3, greedy=True, t_max=1000)\n",
    "        )\n",
    "\n",
    "        clear_output(True)\n",
    "        print(\"buffer size = %i, epsilon = %.5f\" %\n",
    "              (len(exp_replay), agent.epsilon))\n",
    "\n",
    "        plt.figure(figsize=[16, 5])\n",
    "        plt.subplot(1, 2, 1)\n",
    "        plt.title(\"Mean reward per episode\")\n",
    "        plt.plot(mean_rw_history)\n",
    "        plt.grid()\n",
    "\n",
    "        assert not np.isnan(td_loss_history[-1])\n",
    "        plt.subplot(1, 2, 2)\n",
    "        plt.title(\"TD loss history (smoothened)\")\n",
    "        plt.plot(smoothen(td_loss_history))\n",
    "        plt.grid()\n",
    "\n",
    "        plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "final score: 379.1666666666667\n",
      "Well done\n"
     ]
    }
   ],
   "source": [
    "final_score = evaluate(\n",
    "  make_env(env_name),\n",
    "  agent, n_games=30, greedy=True, t_max=1000\n",
    ")\n",
    "print('final score:', final_score)\n",
    "print('Well done')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Let us record a video of trained agent**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "def generate_animation(env, agent, save_dir):\n",
    "    \n",
    "    try:\n",
    "        env = gym.wrappers.Monitor(\n",
    "            env, save_dir, video_callable=lambda id: True, force=True, mode='evaluation')\n",
    "    except gym.error.Error as e:\n",
    "        print(e)\n",
    "\n",
    "    if not os.path.exists(save_dir):\n",
    "        os.makedirs(save_dir)\n",
    "        \n",
    "    state = env.reset()\n",
    "    reward = 0\n",
    "    while True:\n",
    "        qvalues = agent.get_qvalues(np.array([state]))\n",
    "        action = qvalues.argmax(axis=-1)[0]\n",
    "        state, r, done, _ = env.step(action)\n",
    "        reward += r\n",
    "        if done:\n",
    "            print('Got reward: {}'.format(reward))\n",
    "            break\n",
    "            \n",
    "def display_animation(filepath):\n",
    "    video = io.open(filepath, 'r+b').read()\n",
    "    encoded = base64.b64encode(video)\n",
    "    return HTML(data='''<video alt=\"test\" controls>\n",
    "                <source src=\"data:video/mp4;base64,{0}\" type=\"video/mp4\" />\n",
    "                 </video>'''.format(encoded.decode('ascii')))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Got reward: 396.0\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<video alt=\"test\" controls>\n",
       "                <source src=\"data:video/mp4;base64,AAAAIGZ0eXBpc29tAAACAGlzb21pc28yYXZjMW1wNDEAAAAIZnJlZQAAXiptZGF0AAACoQYF//+d3EXpvebZSLeWLNgg2SPu73gyNjQgLSBjb3JlIDE2MSAtIEguMjY0L01QRUctNCBBVkMgY29kZWMgLSBDb3B5bGVmdCAyMDAzLTIwMjAgLSBodHRwOi8vd3d3LnZpZGVvbGFuLm9yZy94MjY0Lmh0bWwgLSBvcHRpb25zOiBjYWJhYz0xIHJlZj0zIGRlYmxvY2s9MTowOjAgYW5hbHlzZT0weDM6MHgxMTMgbWU9aGV4IHN1Ym1lPTcgcHN5PTEgcHN5X3JkPTEuMDA6MC4wMCBtaXhlZF9yZWY9MSBtZV9yYW5nZT0xNiBjaHJvbWFfbWU9MSB0cmVsbGlzPTEgOHg4ZGN0PTEgY3FtPTAgZGVhZHpvbmU9MjEsMTEgZmFzdF9wc2tpcD0xIGNocm9tYV9xcF9vZmZzZXQ9LTIgdGhyZWFkcz0xMiBsb29rYWhlYWRfdGhyZWFkcz0yIHNsaWNlZF90aHJlYWRzPTAgbnI9MCBkZWNpbWF0ZT0xIGludGVybGFjZWQ9MCBibHVyYXlfY29tcGF0PTAgY29uc3RyYWluZWRfaW50cmE9MCBiZnJhbWVzPTMgYl9weXJhbWlkPTIgYl9hZGFwdD0xIGJfYmlhcz0wIGRpcmVjdD0xIHdlaWdodGI9MSBvcGVuX2dvcD0wIHdlaWdodHA9MiBrZXlpbnQ9MjUwIGtleWludF9taW49MjUgc2NlbmVjdXQ9NDAgaW50cmFfcmVmcmVzaD0wIHJjX2xvb2thaGVhZD00MCByYz1jcmYgbWJ0cmVlPTEgY3JmPTIzLjAgcWNvbXA9MC42MCBxcG1pbj0wIHFwbWF4PTY5IHFwc3RlcD00IGlwX3JhdGlvPTEuNDAgYXE9MToxLjAwAIAAAAH+ZYiEACP//vUn+BTUEvxL4Wth7dS3STDRcLEts9AG6uAAAAMAAAMCK5MpR0dNau8UAAAEMADgB9BlB5iJirFQJXhaBmXtwCBdkotuLKLaOXxBYAAD84rYXV9R7BxgVxBxtnekTvaxVTr+B5P4NdsHYbnwHirEBy+nO8pyJKudsYT5m64jXqcGaFeOwMFmSBDpXJKOOMZEHMInC6lMgRwASLrdDzayg+BRXiFeA9JeAifA+8Vs7HoTwYAMEQReyeFa9DVvUIXYRw/LVZ4+HNo9dCmrFu7AX2gxKHKD3rPW5XCLMoOFAAA2DqR0ntm5PXf6/DHYSti3+qO0xr5JjFjHrU4aCbfxCE0eQJRjHxF45WGGgQ3h8faQ9XTwAYiEX+GYgYPKNpUEvs6NSbquK4AAnjW5rP+u4HVVw6UQpNMyoIYPqkbcJl8iNJVAuJbYAxxkFzunO6pUPF/oxzup7d39JVbA1oAE2IdlEnkSH/BDjVl/LsnoAL6FcaqckNuZDfH2loz/6hLCueqIeyTGX8oVrjY3RlUZUxXNQus1z9aM1QufW9WeLZ80QYATj+gRc8OrF6/vU1gAAAU6dsz3l3hG3tIS2gaSxs1dyg1+LFBoatpM0gLTlMQpz5HN3v13jU2/kClVBkp4DwlSsET8A2wCVV5wAAADAAADAAADACthAAAAX0GaJGxCf/3xAAADAp/WvAfjpxPjzIS1jyby90LIPz8JUQsA0TWvjzad2N1JA+0KdFjMiFDo5LK7jOroafZfe3tWHe1kLo+NIjenFwJgxS8tnsa67y8iULhhw+q0cCI7AAAANEGeQniEfwAAFrVcGD2WvpY8S8r0Gi1jCyh/dUKB+KAAJkeiTv+isD2vomHwl8qrbUKlz5kAAAAeAZ5hdEf/AAAFGXJzUh+cBb+M6L8NyXFhKFVmz8//AAAAKQGeY2pH/wAABSCpFqa8zLpXw8ru8FUAD3414F3dupA9iSWM5x01I7/BAAAAS0GaaEmoQWiZTAhP//3xAAADAPgcrOqwO1mL/Sxh1gPhxPKM9+7RiR/QNAlaOSpz9LfT6yWKu4OcLFXXLOBLalmcwNCtNdTudTYr4QAAAC1BnoZFESwj/wAACG8h5v7bLVmLzD/I8TMAHvwlznO2Qg+FmS0iAYLdE7tdSoEAAAAaAZ6ldEf/AAAFH8vusfQhyC524S8lbM3eO6EAAAAeAZ6nakf/AAANhJUtDKoy1+4oZgz3GLSpAfkf6YduAAAAKkGarEmoQWyZTAhP//3xAAADAPgWekBbRHIADajOFgZ1i/VVrdrPKEARMAAAABpBnspFFSwj/wAAFqfNByKhEP1PKzMIngC9gQAAABMBnul0R/8AACM9auGNfJoG0AFlAAAAHQGe62pH/wAAI72DQi+Z6Jf20AJYoELdkI+zlAKaAAAAQUGa8EmoQWyZTAhf//6MsAAARhD0PtKpIAJ0RP18w3GeJHncGQS0hxjok6uBZh9V5jBMP5c7dzaXN6aPidFSRJT5AAAAO0GfDkUVLCP/AAAWb5sii7nkbbvIAFjorGIJxN+f6eDPhekr1zh329W3Xda4FGSaR8Wrfw59E+qGY9knAAAAEwGfLXRH/wAABRxSadWmpZAkA9sAAAAhAZ8vakf/AAAjvxxVpLrcb62HKvFm9xjWwyIJh1XpbkkwAAAAKkGbNEmoQWyZTAhX//44QAAAAwBNT76rMvH2sw2/0dqaAG4kz8Em4lC5BwAAADNBn1JFFSwj/wAAFsCfmbY1UALRMSm7Ke5mh5jlZycAsQ73pVY8WYKCPK75GZIvrK6xkmEAAAAqAZ9xdEf/AAAjw0AQrr3oZDQaCuuTIKbiACZaEOapMHttWl8MPJiCz9tuAAAAGAGfc2pH/wAAI78cCFYhPI5IIQvvaAkS8AAAAEZBm3VJqEFsmUwIX//+jLAAAEYOXyfQBw0he7pF/NLNKCgbrYoLzVUft+Ay2Ogc6kVXHVm4+iWX6oyo86GRtjyt1CSgIFVxAAAAFUGbmUnhClJlMCFf/jhAAAADAAAMqAAAADtBn7dFNEwj/wAAAwAQGyaG2kwA3WJCPadNGSGPasQya2uuUJlDGbc8lZ8C3NuRBwCb7UluK79FzSnqgQAAABgBn9Z0R/8AAAMAGlwBsl2grxyPU3Ci24EAAAAXAZ/Yakf/AAADABpfbTZu+13Kg7/T23AAAAA0QZvdSahBaJlMCE///fEAAAMCn5hEQAKC2nMj4mD9GQ4uJOtI2LAwhhr/p97AyWH3UFfDwQAAABRBn/tFESwj/wAAFrUrQyD60/eBHwAAABIBnhp0R/8AACOr+GeA5IMg4UEAAAAOAZ4cakf/AAADAAADAakAAACIQZoBSahBbJlMCF///oywAABGXsMH4/JKOdgAaA4IyT+bg3d5tsQ464ERuFqMivvm8OfYvUiWGkE4HopnyM5DtwjuYMG1TYY9LXGykvJnRcdZ5Y2DLrKr8MT82yA7pisyf0w9Ucidl/IusKFVLb2UkvDUD5VPRR8m4X4f+NjdkYqgcd2S/qa5YAAAAC9Bnj9FFSwj/wAAFrYlIAcd560S18ofrm/TXBiPLiMM2xvyivMVYeL+ZgR270gfLgAAACYBnl50R/8AACO4r96qcSJFHAdACatLvgddhns9HxD1HxC1GuAnbwAAADEBnkBqR/8AACOZtvhiqPphJsABasAu8D/zS9E+KdLEfftWKv3/XOnv5wwyME+SG8GAAAAAP0GaREmoQWyZTAhf//6MsAAARgLT3gCdlDXJV6DgEiFzHsdgOEVPA5NldfKY5IFVuoqk+uwbB6nAvtJMSKxEbQAAACNBnmJFFSwj/wAAFr51b7IRurMUR1DK1/oHQuztnHPImr9bcAAAAB0BnoNqR/8AACOeTDea4ZbDGvCr6d2EsY10hqSAgQAAACFBmohJqEFsmUwIX//+jLAAAEYR8YACIkNAPzEQRaPoKCEAAAAUQZ6mRRUsI/8AABa8PrcIVyuyoOEAAAASAZ7FdEf/AAAjuLNWqioN0dypAAAAEQGex2pH/wAAI78b2PWy/EHAAAAAVEGazEmoQWyZTAhX//44QAABDUEgQBWIhc1/U1TI33LwrYSV2KwyVXMPlJoNK0RTdxM+iZN9wpMGgLnIS2C2ebzRtJJ1Nwewp6aE9r4cAVtG2Evl8AAAADFBnupFFSwj/wAAFmwdqHIAa3/IFAr5krU5E/LGOAAQyC7FEgDHw3lOTErm0WA/o/ZhAAAAEgGfCXRH/wAAI8MXdVFQ0STCggAAABoBnwtqR/8AACPHvYwaTnQqwcK7KKTbBbHbgAAAAClBmxBJqEFsmUwIT//98QAAAwKf84ASLjkFVxABsrIloI/aD/E85h490QAAACRBny5FFSwj/wAAFrPr1gBbneO+aYh5uHgIiqw0ReVcTWcm24EAAAAgAZ9NdEf/AAAjn1x2VFhslxPIgb2vwAEsFjXdawweNmEAAAAeAZ9Pakf/AAAjrjLDntAAuOnYddpWA7LdPYxf1iPCAAAASkGbVEmoQWyZTAhf//6MsAAARhOjdgDllTH2dQLk2aLBuhPLZNnO88jkGpCIeeI4Suv4fGCwAMbx0Nab2qlcY2jPWxJH1SNMV9mAAAAAIEGfckUVLCP/AAAWpVjvBbkCBJ6EzqkE1146WhhE8tJNAAAAKQGfkXRH/wAAI8CaoZ6DRRgXAAXAOPfXwC9awJpyKc//jH9Qrt8A6ICAAAAAEgGfk2pH/wAAI72EAAlVZuKKvgAAABxBm5hJqEFsmUwIX//+jLAAAEYQ9D+wH7SCc15BAAAAHEGftkUVLCP/AAAWvnYakAOG7RStRVgZLApXZtQAAAASAZ/VdEf/AAAjuMHseu5xGB65AAAAEQGf12pH/wAAI78b2PWy/EHBAAAAHUGb20moQWyZTAhX//44QAAAAwAcP9zCAIA28TOuAAAAEEGf+UUVLCP/AAADAAADAQcAAAAvAZ4aakf/AAADAAo5SJBTN6/oLN4+bqDHyPO3p4ATJn5lzzeXZt9X2FyZbYDOnqgAAAA0QZofSahBbJlMCE///fEAAAMCnjof7ngA+Xsu9QYWG8IwbhLVdFQ0a5Y1Yd3GeDJ9A+EbAwAAACZBnj1FFSwj/wAAFqUvYO8ARIMkUqDgKEn5Zsjdyu7hVhU3WbxBwQAAABEBnlx0R/8AACOsPFGQpTjEHAAAABEBnl5qR/8AACPHxxRkv5/NqAAAAEhBmkNJqEFsmUwIX//+jLAAAEZo2DY3AFaot3XbsjP54+heIDL2GqV10qjZgs50luZRkogUfnXUulCG9KW3L9o3pk30Dgsoi4EAAAAyQZ5hRRUsI/8AABa+pqat+QkLUD35lDxwAZeYtTkOtqfVbj0KYd3yj2CrBd7oMi+r4MAAAAAcAZ6AdEf/AAAjeeJ4YIHwZafyNUGMF6rJMWMICQAAAB0BnoJqR/8AACN+NLph3qDbvLWLo6kXYu7ryf2HJAAAADtBmodJqEFsmUwIX//+jLAAAEYQ9D/A73smY6MoiV/Hw0lpnAEka1YvfByE/kHe4LkU8R2P5W2e+xLr1wAAACFBnqVFFSwj/wAAFnF1yyriJg+1A1SJELFWqfI6OR1YhAUAAAAbAZ7EdEf/AAAjuMIqqCzErNFHfvoaX8onXEkxAAAAEgGexmpH/wAAI7IwozkzKYHmgQAAADtBmshJqEFsmUwIX//+jLAAAEZexE8OmoAk2BBOuX/PCKfXlJ9b6DD5anelF2bORkHbFM9rM7F6ul43TAAAACJBmuxJ4QpSZTAhf/6MsAAARhHkQAqIKj/sCG5ISrevx0l4AAAAF0GfCkU0TCP/AAAWvqOeIINNX8MTosr5AAAALQGfKXRH/wAAI4T9HMyv8RMBQxS6SlLABONEA8IZCboJ2KtuYAe+Cj+X/6zdswAAABIBnytqR/8AACPHxxRnIImMDzQAAAAnQZswSahBaJlMCFf//jhAAAENwSZgFBOhkOc5Ew3vKeX6WM7M63W9AAAAGEGfTkURLCP/AAAWnR0YuIQhCuaYPgD1wQAAABABn210R/8AACPDP7Hro/EHAAAAEQGfb2pH/wAAI78b2PWy/EHAAAAAQ0GbdEmoQWyZTAhP//3xAAADAp5AStjO75yCH5Ij9ACE48H9H0hDjWs4qZZM6zk9CndcJ8/URna1lqyQPiwITQLEdOwAAAAgQZ+SRRUsI/8AABZwvV3/mmTlrWf0+fLHC1i4SLBvP7cAAAAnAZ+xdEf/AAAjn/rN6yHeQU1y+/+I6bGpjstxaABLIZyfSQrvzY0HAAAAFwGfs2pH/wAAAwHx7vmBXcGx9wbDJgRcAAAAIEGbuEmoQWyZTAhf//6MsAAARgLQ+Z7Kv4X8dMBrwBJxAAAAJEGf1kUVLCP/AAAWcXZyTlcR5ywX7Hb4AwVWL8ACd3KA9cTn6QAAACEBn/V0R/8AACPDPg6IqgAtwA0R442sJMNe/fORLhr5YPEAAAAsAZ/3akf/AAAjvxvaueYf0o4ACdYaQySn8JWt6ATyBpPOi4xkfwg912tktmEAAAA1QZv8SahBbJlMCF///oywAABGK/+QAAmlOeE9m10uH//7+pqX4F4KdzYicPtGsfrjbcypriAAAAAzQZ4aRRUsI/8AABbAvnwBEgQyWGJYr0/f0C3mS/eaM+cV+HJFLCJHn0mvpn4Jlc6JLP7ZAAAAGgGeOXRH/wAAJMMXdVjwBbU/CFZkVgx8qh+2AAAAHwGeO2pH/wAAJLGFoLhiiXVjw3a0XNPnm8MV9SfD2zEAAAAiQZogSahBbJlMCF///oywAABGQYIb4QZgj//4ACnkrbPD5wAAABhBnl5FFSwj/wAAFr6muFVEk2cpl/Z3wcAAAAAUAZ59dEf/AAAjuMHtU+JmCncU1BAAAAAUAZ5/akf/AAAjvxvaqYOH+5A2YMEAAAAdQZpjSahBbJlMCFf//jhAAAAOd4uAFeOdUboVdbMAAAAVQZ6BRRUsI/8AAAMABnN32UBLci+fAAAAFwGeompH/wAAI5n7dA5yIS3t2y2MI2YMAAAAKUGap0moQWyZTAhP//3xAAADAp8CxJh89gBNMe4x/CGxibBIS2/F813BAAAANEGexUUVLCP/AAAWqpjNqsMVb+0G1nHXcgXgCPVkQAQ/CMdYerhXyrxRDPVtzT3W4NICPB0AAAAxAZ7kdEf/AAAjrEJiFN7VayIjRq2gAleD2BXpizUBNYc2aeXksKh1l9UYNyrkfhzAgQAAABsBnuZqR/8AACOUA6/CXg6n1Zijo5V+Ge3Q1asAAABnQZrrSahBbJlMCF///oywAABGEPVMQBvOVO3zyTOmX7cdS8lzMGuBm0N5LZ8gwzTRGwV1xNy5eSj4hcD5mDsJfoTC2j6MEX77H3MMTAjhL05Nz59/6+gLW0xBHzmIhg7+mkgsB4PnRQAAADBBnwlFFSwj/wAAFrxOGEuue8O2ggATMzsSwSw+3Qu257KxQZG6N3IZcukbOlIlMCAAAAAaAZ8odEf/AAAjwLmVu+7/hU1bkqOQKrxFDZkAAAAfAZ8qakf/AAAjrl/7OIq3utowHmne8X2paeevturgQAAAABxBmy9JqEFsmUwIX//+jLAAAEYRwKeE96i7s1xAAAAAF0GfTUUVLCP/AAAWvE7hNiSOMkroBswfAAAAFQGfbHRH/wAAI8C5kg4q7mS6Gfnl4QAAABMBn25qR/8AACOyMKfGBgL1QMwfAAAAF0GbckmoQWyZTAhf//6MsAAAAwAAAwNCAAAAF0GfkEUVLCP/AAAWwJ+QfHqmDlERccaAAAAAFAGfsWpH/wAAI78b2nPihDdNtpuBAAAAMkGbtkmoQWyZTAhX//44QAABDUKGAAoNqIm6stD+BSDY698sDKgPAub+zXqUGF6PS8YEAAAAF0Gf1EUVLCP/AAAWvE7hQrrKg/EbO01VAAAAIQGf83RH/wAAAwAJaxDbqj7O2QAAnbtIcmcnNAjvMzyqgQAAABUBn/VqR/8AACO/G9qFf84NL+uci4AAAAAxQZv6SahBbJlMCE///fEAAAMCn8pZ4WPdXLBBAPjoXgSCcIM4gAfy//k1bGUYNF9/gQAAADJBnhhFFSwj/wAAFrxO6QWjfK2AG5oJBCQ7edX4Nd6PNTcX8gIL/eQ8tu81tQxbHiZqQQAAABsBnjd0R/8AAAMARYZ8Ic7qJQJLzoSPOpDBVNoAAAAdAZ45akf/AAAjvxvqITPiMT6pOi1pJRCZ+4F2rqUAAAA8QZo+SahBbJlMCGf//p4QAABFRQ01gAjI+261IboMNYPfROy15r9x22J93zQ31Rt0kec4Odwqw7kyfZkOAAAAMEGeXEUVLCP/AAAWwJ9x0RckEmb9G4QAJmZ2OYHd5jn+p2d9TC7wA/IayWLOclKziwAAABwBnnt0R/8AACPDQBCvY7vcMVspTQYdjN371U2hAAAALgGefWpH/wAAI78aznwXckpZtgALH+4Bw4Q35vqqD/yzd0geqAcuXTNKenNRC6kAAAA5QZpiSahBbJlMCF///oywAABGEPaWcALD6k98qT/oYzTyDfMjfj86Kxd7KpRO1Ms1+4MM6n17nZVgAAAAI0GegEUVLCP/AAAWvnW1gYSbpTRaUpWslZycgFb1N9D+jPj3AAAAHAGev3RH/wAAI8NAsTE0TTfZxIP3tHodMhI1+pAAAAAYAZ6hakf/AAAjx8dI0GwENrGhcToCBFNBAAAAKEGapkmoQWyZTAhf//6MsAAARhHAp42ExAx6BK/Fwhu40NbSjTEe1g4AAAArQZ7ERRUsI/8AABa1WwMJ9AlK70kVPoAJ1Pld2Vsyuc9To1D+i83pWxz2pQAAABkBnuN0R/8AACPDQLEz2yuK12LI7cwlInx5AAAAJQGe5WpH/wAAAwHxf+T9iz91g4AEwT3vr46Oiw0J27JkA9WRW4EAAAAeQZrqSahBbJlMCFf//jhAAAADAB5TNPnjtErC2BQxAAAAFkGfCEUVLCP/AAAWvqbIIydpKj5Mmm4AAAATAZ8ndEf/AAAjw0CxM9fdBEOF/gAAABMBnylqR/8AACO/HFj4a+md7LyBAAAASkGbLkmoQWyZTAhP//3xAAADAp/KWeOzqugA4uF7RLJzWF8Bnedr2evoyV94axx28UkSSxgSDg+dVZXReMh+8TQaHayvJwvZIniAAAAAHEGfTEUVLCP/AAAWvE8gjPqYpcHishNNSwfh5TYAAAAQAZ9rdEf/AAADAfCKPYB7QQAAABoBn21qR/8AACO/HFj4cX3ST4FfRaWSgZkRYQAAAFRBm3JJqEFsmUwIX//+jLAAAEZc0VcACqQ5OQ7r6vJbT5Ep00SetzRfHGoBdJEovzey8RQm304lS6IG/hY8Zqe3YOoRodINErqBL+lGLIRIkFmEipsAAAAsQZ+QRRUsI/8AABa8TmzC6eRyYSgBLVADU2njpOB6cVItIoRVL7iEWi4cb6kAAAAXAZ+vdEf/AAADAfCJB/OGWsI+/vfdhcEAAAAqAZ+xakf/AAAjvxrOZqPgAWjO287yF7oQexI3FNa4acWqysrJB0lY65wRAAAANEGbtkmoQWyZTAhf//6MsAAACgYqCANuyv50yO3Z/nts9Zle0DpccBL/ehggF3EJmE1dSTgAAAAhQZ/URRUsI/8AABbAVpMpusaY0uEmHqOOBgrs5srlFR7gAAAAGwGf83RH/wAAI8NAsTPjAHZkgvZwxfHhSuJIsQAAACwBn/VqR/8AACM4PhAoAOJvijI0dSyEhWvqvaS0uO/Oesna7Q387exWwhQiwAAAAERBm/pJqEFsmUwIV//+OEAAAQ0/ZJQ+PgClN81zN2gnzzHRDX85YWQTWD7SB5hw25ffB07PvmqskoEtek1yTh7diCu+pQAAAB5BnhhFFSwj/wAAFrxPIIz6mPLglsNB4JN5TgQd/IsAAAAcAZ43dEf/AAADAfCKRS755pZb3WOUGKfZlO/akAAAABUBnjlqR/8AACO/HFj4bYNcM4Et6YEAAABEQZo+SahBbJlMCE///fEAAAMCscGKLyT26sTa6mF8cdd6O3+rRAJvi99yt+uyY3eveWFRP00Mu5czEbIjBuANIO45EnAAAAAiQZ5cRRUsI/8AABdMQ8+aYOPZQXTvHQ1Ug0jJA5TsUsN73QAAABsBnnt0R/8AACNFaMdkXj7koIdJfgMj6p1bdqUAAAAsAZ59akf/AAAkvunLhVFXJmbucQZLifPABwaEoo/TP74G2nRt87iT065nM68AAABKQZpiSahBbJlMCF///oywAABIEPPQFrFGLgA5cInu1vkedQSULK/KOfKNIm5lxWQI1wKtonIXjEq70XHRCHIY8HxPgq7gH7U2O8AAAAA0QZ6ARRUsI/8AABdJOIjZn4TIfcAQ9ZVFd3FRN9ravXc8gf/HXqNrf/AmkDIRMMzoCQORYQAAACIBnr90R/8AACSsOiahibMAIG9VM13C8H5XsVfAvNwbQA44AAAAHwGeoWpH/wAAJL8EJdpr/yE61e5+Lce4ol3NByXzj3EAAAAoQZqmSahBbJlMCF///oywAABIEawRCGh2aZCtv0MOjgU2IAiZvkSdgAAAADJBnsRFFSwj/wAAF0UrQzKriAARkbMsQrtAwMzTr1z/kUJSF6bJ/q39xP03KgChvlNrwQAAABoBnuN0R/8AACTDF3VoigoDYwva3J1g69B7gQAAACoBnuVqR/8AAAMAR4Q6baD8k1gpIihwgVDajsnj1wIrNyKEt6ZtTgic82kAAAAnQZrqSahBbJlMCFf//jhAAAADAEe6JtDEMQ0RhJ2AyCPS/i1pUqs5AAAAGEGfCEUVLCP/AAAXTqOeIIfCQuQZOPMHgAAAABQBnyd0R/8AACTDF3VTNp2dUZAvTAAAABMBnylqR/8AACSxzCqiolN2DryBAAAAgUGbLkmoQWyZTAhP//3xAAADArHJIqUh5mCCXEAF1Gdxf++Se2xjJgmNMbmOWTaWB28u+OH+q/6Sn1i/s/2ZBmYBNw2lIToKUt/FVrHW3UtfSV36tiPn7DaKK0vY+l4xAlCDXt/CddgpvBwenqdqA1tZBkUTQeVlCuOkn6dQibDqgAAAADRBn0xFFSwj/wAAF0NCuFIIm4QAHBpSjqdaO55ULbULXPUZG09et7A5yFPVlPsUgGr+R2vAAAAAJAGfa3RH/wAAJKvYOyY5hIw/6ZMIIlLJLiACdXNPim9Gy1QXkQAAACwBn21qR/8AACSxzAlv20wVNZwAcFKB0MgHRxSerXrNa69+P/hA/4kgzhllqQAAAGxBm3JJqEFsmUwIV//+OEAAARVAVgIcMJ6Sh9D9Lyw5Dxzr5vfvtruW/Mba73mjEF+nRh3T+kuCGibinHAauCyrsqll3Et+rRS7YnS1S6V18AZZrx9GlpSSMC3EIdatJtSqcjEdlOf5rcoYPcEAAAAjQZ+QRRUsI/8AABdLikjp4cw0CZxBMpIKzfi92Lnvr79vUiwAAAAiAZ+vdEf/AAAkwxdoqbKr5AA4LNvaUnNa2q7Zc0ufVKAMWAAAACYBn7FqR/8AACS/EakgA3JHdnIrp8MtBQWGn1W6XbWanWy7BY0iwQAAAEhBm7ZJqEFsmUwIT//98QAAAwKxc6+E3cPz02I/HBcJ3Uy6cMcshX7B5LoUxqdkF4ZknpaCvAKLMILD5oLj0cMHxHKPhrMEOFQAAAAZQZ/URRUsI/8AAAMAENf124uoulXKcRdK9wAAABkBn/N0R/8AAAMAGw+FPQitt6ht76aVbO2pAAAADgGf9WpH/wAAAwAAAwGpAAAAK0Gb+kmoQWyZTAhf//6MsAAASALPV3/UP6AHLtn/lrg4csRJVzD5TSx7raEAAAA9QZ4YRRUsI/8AABdFTMJABx5RiE3PTfOD+xgi5e6tv1BaP0R3OVZ1GZui33WmPPVV3z8Vvi5/l8GWn1QXkQAAABUBnjd0R/8AACTDF2ippVTfotrGC8gAAAA3AZ45akf/AAAjvx0w7QNtWoOXu3F/wsB2AfRT3AWAABZA3fQm+XxxG6MOENVDLJKAt39b65LsiwAAADpBmj5JqEFsmUwIV//+OEAAAA7nnox0qtyd++3phkBHvPvSvdNml5j78+YskX8A3C1Ju7EkTEIABDY+AAAAP0GeXEUVLCP/AAAXRJZtKAEYfjzFXBEGD1/sNjFLPsihpQsrUKEGE4E2Zv6b7AJCRu+35PtCeq7M731rU21NgQAAAB4Bnnt0R/8AACTIYSU5RQEnYUM03MQd9JFe80HjHuEAAAAUAZ59akf/AAAkucFrd6ioXfsTryAAAAA+QZpiSahBbJlMCE///fEAAAMCstXt2BOCuf4gRQSTQaJOnBMnGhqA5pD72yEcJ1PdWHRtF1akrql5r7k2I6oAAAA5QZ6ARRUsI/8AABdLin5ebAgAJxiWEnHy+qclrEkIIhDDZO8ZyHj3T4gGAYuJ8lbzh+5ar06zxaixAAAAGgGev3RH/wAAJMMXaKnFzCHAJ9rcnWDr0HuAAAAAHAGeoWpH/wAADdJO2bKmQoVgktpkeaBfe2VhWpEAAABbQZqmSahBbJlMCFf//jhAAAEVQFYA7RaTAazbvV+vi7bzxz7hyoXuHCLzxmbwELe9xxclHhyInOjsT8k51aLa2m7HYQbedR/qQ7an7aC0v/o0HC2o6q2HTA1FTAAAAEBBnsRFFSwj/wAAF08KdK19CABYJQyP6XF0sH77G1Lq2Z4VxOlnpRhH7TLPJg06Z9GP9eL7CpSCS395f3OHOg69AAAAKQGe43RH/wAAJKv4W3gX1U1byQ+roAC4n0NTfEwKhDvwoyfKxIkttQD3AAAAGwGe5WpH/wAAJLnBemexJP2G8K/+i7Oz/zM68QAAADpBmupJqEFsmUwIT//98QAAAwKxArucfkB3qrPzoZwB7O8Aa9U8QunqwfMzeN5ejoHlw0ONbjz2FyyhAAAAHkGfCEUVLCP/AAAXTEPNtxdKz+GF/KRsQAP0ZBq2pAAAABcBnyd0R/8AAAMACoeLEiZFiFgWe6cnlgAAABkBnylqR/8AACS/BCcS0CdlDYcKQZcXeVrxAAAAV0GbLkmoQWyZTAhX//44QAABFl/G+MYqpiBi4tS7pimw6TDx7nSSaedkgjAu7LL7xHHwoS2eEPH5zPglBMv+nD1yq4S4Jbib2Ex2GTU6AiUGKcan627S3AAAAC5Bn0xFFSwj/wAAF0xDzT6PB5jjmACZqSibSqI42itY22yyXukosonCiMxjICOvAAAAJQGfa3RH/wAADc4A0hQZwASOrZ60ZRcJqq3FkvDwA5VGjq1VWvEAAAAdAZ9takf/AAAksd5PaiiuHpkvlhUKWPwIGktzFqUAAAArQZtySahBbJlMCE///fEAAAMCsxi9JfqgcCoGx8mcCFhjSR2NW6Zu+jK4gQAAACVBn5BFFSwj/wAAF1CcaKLWEvP2y4AD90gMFBBdIVGjVeCBmgRcAAAAEgGfr3RH/wAAJMMXdVFQ0STCbgAAADABn7FqR/8AACPYXMARMXp6VIOdJipplgd6xyr7XgeEYh7yMgrrpaV0xCWYciI/e4EAAAA2QZu2SahBbJlMCE///fEAAAMCsb1xI7qZKkAJUfWjXEaEungGuS7GQJAO8uAvARr7eS9ewJeAAAAAPUGf1EUVLCP/AAAXTE4YS6iIKsSABMzOxLA/Y8tPw1yD/6ZW7xxwrYi99EC8qUCm6HSFXiNWzaqtLWHl2vAAAAAaAZ/zdEf/AAANzgDTYQyIeLb5bJ1Xs4QY68EAAAAbAZ/1akf/AAAkvxxVXxbKNuPWvZf9uSJ5AteAAAAASEGb+kmoQWyZTAhX//44QAABFee5pnioDBzxYC2ow21WafULOqvEG0/Fyo4vqPxd5QA51mU9H6YFShP0QX6HHNvG6txPBc3BDwAAAB9BnhhFFSwj/wAAF0xDzbcVzKyZhifqie/og1VjKwnBAAAAGQGeN3RH/wAAAwBHV/C28E8ktrn2fLs8teAAAAAhAZ45akf/AAAkscwJb93ZIAFoz5szvkUQpUs5D+ZwQGLBAAAAUkGaPkmoQWyZTAhP//3xAAADArGXqDcB7+7SWBo3Twjr7YCb5m/3PuGMtDcqdcqCKp1eus3vHNvUX26MDNKp/gEH6f4MznhE1Fm57XadTBXOg0AAAAAkQZ5cRRUsI/8AABdQVpMnAyvCXnI6o5yjc37Fctbjs8Q0tHuBAAAALwGee3RH/wAAJMNAqpfhNvIEYt9PfE7eaYgAlx2pric+Gg1yYW+dkCk9b37ESej5AAAAHwGefWpH/wAAJL8cUtl3KzP0jth2Z5vS6rT72Rage4AAAABNQZpiSahBbJlMCE///fEAAAMCs6ZYQk1iAK4PLwAEQduQxI5jlia3aztcJHRCU0/1fGgY2vXNFZv1bE3xLKuumqJaSpebF3bcKNCLh4AAAAAzQZ6ARRUsI/8AABc0+tkSGeGEz8QA//89E2GbPjHZfCVYo4o6MtB545PFi2tOr9QPFTBhAAAAGgGev3RH/wAAJKv4W3gSnWgkWITMs2MUpwOAAAAAHgGeoWpH/wAAJL8AG2qDeawm6AEsGRr+V0W0GkCygQAAAD9BmqZJqEFsmUwIT//98QAAAwKzGL4c5l2BLQATPEF1cg0LaHxJ3trgJuAz9trKMrUMvS/biz3RAx+ungkGjLYAAAA1QZ7ERRUsI/8AABdMThhLqIgrXdAB+HgUfqgXu8n2xLePBRihmYtd+zyzK+ujMU6kDUif2FsAAAAwAZ7jdEf/AAANzgDSFI5AAXE+m5SdQG+wZyMTCtcBmDQt90/yS85aZEcmM707UjgFAAAALAGe5WpH/wAAJLIyO+USEpfE3ahDDsS+ehfOcu+7AA3Md8mjgf30XrzSLDqRAAAAUUGa6kmoQWyZTAhP//3xAAADArMQoMw9AW/5GzZOSgKDeagrEPTHVbCUufXalvhsJrMUSOyRP0vp8Ed4tUMGFLdY56lbo6CxL8lvvtnjOXyE/wAAADtBnwhFFSwj/wAAF0NHzqsFVWCXUEABOHTXcwokBKzMXkIS6hV0uE/xWaiagHjHk6w8UHF5hl59uRI9qQAAABoBnyd0R/8AACTDF2ippVPVEFT0kSabsUJ3uAAAACUBnylqR/8AACS/HSMfnqhmS+RIAEOcm0HRo2EWMAAji/NdyD3BAAAAa0GbLkmoQWyZTAhP//3xAAADArG6f7ABOWZM7LbtlTD9SUZqIPdU6TtSYuaKB+M5m3GlQnttwv2jfKIUnFKi5H5+qaA/ePa1Nfh41pcMsQRk2JLx1cVafthPJVGhhARRjSN1nPCId8QizVWAAAAAMEGfTEUVLCP/AAAXTE5hd3AmgqarMX4XlhN+4OtOI7SGYg5wr/ad6+MrdO6cyELXgAAAABsBn2t0R/8AAA3V64eMshRs+CBw+V+4nytpD3EAAAAXAZ9takf/AAAkvxrO2rTGkmcIqjRzd6cAAABdQZtySahBbJlMCE///fEAAAMCsbp5qZQPQdVwtu1AIxfcixWNcmkvVV16MIPVqnVLkfNmuOl6eGVSIQkZi4o4E9DjSIc7k1QDEvUavIi/jsqVtjLMCzImOC6xPWLhAAAAJ0GfkEUVLCP/AAAXTE6d/ZY43SrLbcloBKY6vAbnAiS+g9Xp8wYOCAAAADQBn690R/8AAA3OEkoREJnaFNVuR6ACDALebidLgATt1xLLjJjA69v7rY27ist6H+82CFrwAAAAHwGfsWpH/wAAJL8aztq0xpoJ00rHLJtwDreUUNpwPcEAAABBQZu2SahBbJlMCE///fEAAAMCsbp5pdD8JGdC7rxvGRAoIiJ5nACbhqBiUEIPFZGDxDAlHnf3T8WsYCzZOt13o60AAAAsQZ/URRUsI/8AABdMnXgCJBx5mwKt8RNIGGAi1OUQ/XJ604xgLM5L93OmV0wAAAAlAZ/zdEf/AAAkwzufqwFDJRWu0TgAnEcTOlcCOG2UCZBsO/jg9wAAAB0Bn/VqR/8AACS/Gs57+ztB+Ue22XL9P1z8KmiIsAAAADdBm/lJqEFsmUwI//yEAAAQTASyMoWUXySRQvgAW3e6l0NESGObIHx4XQ3MS/7BxsuVpSgQmO6BAAAAJ0GeF0UVLH8AACSf9oLS1TDDcd4y3YqAEqgbDo6ApXZkD6KLjZxGfQAAABcBnjhqR/8AACS/Gs84NyhI5Lo/o/WSJgAAAa5liIIADP/+9uy+BTX9n9CXESzF2kpwPiqkgIB3NMACEIUAAAMAAAMBoA4R+IWBIPkwAAADAOMAKCFgEeEqFsJCPsdVgKddfIECPXVEyqc9+Zu44G8NCUtDY3stimwZ/vN//pmgEOFNytYoIxurKmCOt1yH4up5NascA5N/4144U9nBRddU8pbQlyJVBY5fm4v8j5j314A5YomIV1EyscvKeX6MhhopdTQxXRXypvQ4nHH3GAB9JClQyZTQFu3W5VLtPw+2Vt5wAA1omxva6FywCJCEKMnEhyjG+WwE7TxHljnBPFnCUIlZc75LN+yJ0wPlAeyA2qHdHLs4JKxGegpdNI2XQZXqClhbOpAuKASVk8fr9o6v884qDWcf9SzYhybmDGtRkCvir9Vgum6vC8khaz0bonY+XOl22aoJUK0HKnwkhP1QT7Ff8EGMIXvTpZjSufkB+0ls69zeHA30HeSZj3ITnuphCXSa3cFFtBAej+gbarLm+c05nF6wqAd9MM1clFDJA6pc13ivYMJzK3TTOmAlSW/K0I1YF974QJCOLJTxjngAAAMAAAMAAEBBAAAAbEGaJGxCf/3xAAADAsNJigScmnZK6x0B3Dd2TGu7cqCW3cHlvRunW0aS2f1vw8erZjWenAMtvmQKJPzjruvwENJXyzyZnrFK67PKv+/z5fnAI4w9kfk+jDhV3bhQn16abvjEj9lXEun3qOOPwAAAACpBnkJ4hH8AABfric/yQAsON0hAMJjOIFuyBK/+biFZfDrwesu9vGh5TbkAAAAkAZ5hdEf/AAAkrDbhiWAFiz4E78hC+7Ygn9Fbv1AwYLKyQrpHAAAAIQGeY2pH/wAAJb8LJJb7/5qw5BS+KpgsOyWmWi/CqhfPgAAAAF1BmmhJqEFomUwIT//98QAAAwLDunXbEbZKkRdfT2FGv6d0ONz1OGcdMVeyNpeJmI+mn+UJSlFDTny4/13AP3c6uOarptit9GfEwfTSScINBNd17gt6W1jQSuk/o+AAAAA1QZ6GRREsI/8AABfgiBcq4Y58Xpb4xK1BT7ny2kARkXGotG9NF8mZOOAVU1dIcQaxfKJs5/MAAAA0AZ6ldEf/AAAlq9g7LDClr/tVXnszd5Tni0lSUFN/BvAB711az+aP2u9v2YYYIAZ+OzC8+AAAABoBnqdqR/8AACWxzAlvhD1JG+aA9vkPJiEFIwAAAFpBmqxJqEFsmUwIT//98QAAAwLC9wR8Fdx1YLOS8D/kKeLkXIHMybjfF0VbsZCxWR+Ke1a5ehiy74GKEb+0xqBxKL7LCTTFiu6kiJcUvxDPRez7YGY2V5gAoUAAAABAQZ7KRRUsI/8AABfgh/txYK7HABEsfiD9xQmM6n9A2XZb4Kff6hHsWnECy5ZFw33qf+wfCSpOiBCLclVhKUc2fQAAACcBnul0R/8AACWr+F9VcgHzLZebH6FfStvq/A8E0GmQnONvU3aXdYEAAAArAZ7rakf/AAAlscwQRFLHO/EssegAbrS+dmdaCOY5HXw4lQ6HtVaz8WD0XQAAAFVBmvBJqEFsmUwIT//98QAAAwLC9thnivf5FlNghQHnDzGfabLZB7VvSld/QAh+PCwVH6kZYmt2oLh77lpHcinptWwUOHuxWLA/tDGblwYKXnsFFbTBAAAAQkGfDkUVLCP/AAAX4Ie3Df/OJOwXUHq6awwunuAI/o1vBOy8596jI/NShCApvW9VjqvGVp8tlWp3nW8Ras8RL6ltnwAAADEBny10R/8AACWr+F+lVABZCNnrZdGbBnIvy3TB6bQeieq6d3PpAXNR9gD2G6yaz8HHAAAALgGfL2pH/wAAJb8EJxLK/n8pwASxT72NotaD2o1lZ2sLa/01LngEKzDSIhIimz8AAABeQZs0SahBbJlMCE///fEAAAMCxNQXttlnIfNI6LfVo5NVACD6WaaWwdS/Uv0mIFKd6DhLmYYRE5l8Bd2ByGBG/uQVZJ964X+mIVDBDBlIrrANfd52G6VDr4e0VM0EcAAAAERBn1JFFSwj/wAAF+CHtw5Gb1iuOs6gPl2BHRxGn2eiEflnZxYdgE6dX088IMYtsaA5Gxv/WgpEAmi7Q7F+VxiKJJ+04AAAACsBn3F0R/8AACXDF1KENGKIqPzKxHjAC26rf01934rP8kv9VSErn1O3J8wJAAAAMAGfc2pH/wAAJb8EJv3EQ9uDuYwAsWfNmd8VxLnzwPSueRujjLhZsm9I3Na09v8OnQAAAFNBm3hJqEFsmUwIT//98QAAAwLC9uW+DvgePW/d30ZNeN0toMa3lZwCWFV6HQAhumSd4NPq6mueVUiLvsrWFJk43IASzfe/WrcOpZFF9Q7jBaQjgQAAAD5Bn5ZFFSwj/wAAF5UsoOkDZqsKMLYegAfh4FIArJ4BuxOg1Y7r34NXtvyGC0WbF1KoieJp+Logwn/qkeVTbgAAAD0Bn7V0R/8AACTYXMAVghf5nCl/0ZZTKQDj2QHUKmh6DNyMCmbe/gelg98PacKmPluAqzyxJr+aGum4T/7rAAAANQGft2pH/wAAJa5e4nsDiX7P/bAACWqdU6etVZsGX1MYd87gYWToDptK0jq4JjHtQLmSrs+BAAAAbkGbvEmoQWyZTAhH//3hAAAEU1vSEWs2DlrciBe64jpHVSfvfwhvuYHPIAcocD2AUxOn8gewRzkMhdCe1nSMn0v95KEu5zqSsQ85p+kuii+3+MxcKmXKCvy/GI6G+XvaoXoJVNCGncgrM1H54kGAAAAARkGf2kUVLCP/AAAX4IiSUS41bksgSpQ1XtqG2qddXt4bUphx7bI0lE6UsgOHzMsv8aqghIPbQLKDnfqsyImUMjQoFP/E7PgAAAAqAZ/5dEf/AAAlwzy1N/jOhISDy5YO/wBHZn4WSPUK5sm/0B2N1umrlFs/AAAAKgGf+2pH/wAAJb8Z39osQNv6aDABKa1wnHX4AAw05tD6ceN44sBYOw91gAAAAFhBm+BJqEFsmUwIT//98QAAAwLC6O1dAFBsynvHmlQdvDmf/fbG+qirVYGEBglwFTbNHzzUbmqVnnIaiDL8TNdjpjcoGmdEllORg6cP2Ne2K+CEDVl/6UeBAAAASUGeHkUVLCP/AAAX4IiDMbeg7otlB1ytn2EdPZTNulX3CNQk+Qri6mnrjPssxS0rqz/hTetNfSYDsDEAhtd02aXabVwlwTiMJBkAAAA0AZ49dEf/AAAlqer3ntIAC6c3v7yZFJHeAiFft9shlOS+prhiLHuT9INqvt4sxc09TCGpDwAAADsBnj9qR/8AACXHCDF+ERY3wALnqt7ceecn32dOl1wif7CZEG0qprYYc6J71ivfDbZcVrDNLCS8XYnY7QAAAEtBmiRJqEFsmUwIR//94QAABHNbupnDO2Wo38stR/2ReMv0SU7iaALkgCVDfi1wSqB5kE0D/N5A+qee7fTAEsni1Lf8B0HidaimqaQAAABVQZ5CRRUsI/8AABiJgxao1JfPqA3+JOdy2v0RbsHrscJc53uOS10104kP3Uk8CHYCa34Hwfa2Ypru4zFoWkcK2/Cfa3BeXQk6FjnwHRwiJJAiCDP2fQAAAD8BnmF0R/8AACW3zCAIfbangfD9HgoZ0IFI88ALbqt/TcruM59BAbxXeJj/oNeqJ5Kw2h/ub3Hh13pdgol1rkkAAABBAZ5jakf/AAAmseg0IEIOqAHEsxCuRmUa3PyX9B9aed4hV41iQjVwLFwvZmVfOTzc+fUOT0spYoPL9fUr0JB0+SAAAABbQZpoSahBbJlMCEf//eEAAARzP5Xg+lity6WoCc46tLTHQUyaeWKvCMPjAyM1nY9yf8DSb4GKUg0oRmvfQPDxSZJHkMuvk0V+LRze3jTzC3/5rFZCb+surfgwNQAAAEhBnoZFFSwj/wAAGICHtw4smK6o09DuEDKUKIGILl6TC70oeuX3As1JKpcKg7qrYoRdmO2N+7h/xUmX3tf/OIQs+vS+rdu87PkAAAA9AZ6ldEf/AAAmwJkfz2WgQzQAllNfXJiT9XXwi7Xv9Y6bhbX+D1+0fkkiuDh8/e+K0Omvvh20tsx19yhNeAAAAC8BnqdqR/8AACa/CwcDdsBLobdOXwRbFfcPa4cIpq2/PNSOOger8DLND8ar2X7KgQAAAGtBmqxJqEFsmUwIR//94QAABHM/yzQD83llUSB39OmQI0dF4HKauRO0R4/APQRN6qPQ8S630J6yDshVgeKpNdcTb1Wp3WrJUlVewmn7zBXEm3gC2Nv0EceuMlRO7YkaAU8c50QK6cUCnN/2wAAAAD5BnspFFSwj/wAAGIibbqbmdAn1KRmKL2e0np7k8T7qn1n+MKFBnQ/TJgBDQrZ0bYx4qrspOGAwCSpyBltWfQAAAEIBnul0R/8AACbAmd3paNQALcANWkfGJsGX0mTYY7sd5gS/1vdJeGRuDR0+CEmn1G4G63aL6H4zLgPXNfFBQO2dbKkAAAA4AZ7rakf/AAAmvYOBygcsv9K5KQoxoX9dMW1r/QNtk3YIwAXUStcxEZZrmKAKw7nX30YUHdKi2VEAAABVQZrwSahBbJlMCEf//eEAAAR0tXo6GBoBTQVjak8smqf/oxjPCno4jZXwj4XMtZ/ms0mLVEf6WT6pScMHlGLdRd635gFa7OcGUY2mf/mvhuPWBR3qoQAAAEZBnw5FFSwj/wAAGH/r6LRTNwyc15g9b1RiAqMrOgKS85B6isEuW9MTMo6vhMoWurQXVrgA1IGs7FJp85TzlQ7LhLamQc+AAAAAMAGfLXRH/wAAJp9Ni/5fjxFOh8uN59WdLHxRIi8iu6fXo5+KjVQFz35rThP8XB1WfAAAAEABny9qR/8AACauXmkGwZyZkfnT2/RAI62Q8dQ0chvyA39F4yMSkwMr+dUnK4wASs7mpBRd8VWd7SdowL8dtO4RAAAAZUGbNEmoQWyZTAhH//3hAAAEcz+kpIeTKCjo/6QvZWRa+iMeM62zXSQcAEmZPvN3Xl7V2S5/FacpIqasID/u8UU2+ZZeH8a0iImyewrbBIGODnMY/nM7CpXwSeKmjufeIuf9GURUAAAARUGfUkUVLCP/AAAYiJwi8ARG8FYfiD2WF/qU6o5oe6M3v6XXsUNuqYjr58DOvzQT6tM+XBqgiDlf8icP9nnmJASKNqDsqAAAADMBn3F0R/8AACbAmpXJCbMF4iUE4eRR+ifOIj0/0VA4aREFp0fcoANnDOILijfsDtM058EAAAA2AZ9zakf/AAAmvYQEBSxxR9G4pTM14AbkTAI+YRAC21MY3FU0d/5GzxCNyWcfMPWw/OT34s+BAAAAcUGbeEmoQWyZTAhH//3hAAAEk0pTigMbJBSaRKQs728Qvdgii3q3VNDI5MmcRlWbgt/3TsmDvNw/Xii6QTkEK8QznCDmvpamIPrKo9a+YB2LPqyzTu4SBlR3/jQpDqQ6Nes83mP1XwcFBLTBIg/TaZF5AAAATkGflkUVLCP/AAAZKGMxS2NHCSWXGBwurETTLEpTuykzhvtCpWNqjJVVnHzxBumzsjbd7JgAqLvNq3lM898Ms5+UkMqvCaHy0PX3cBEcEAAAADQBn7V0R/8AACfeWec2WgELN+WvsFaMYv1Ci84809PeQAPwq3CJynhfxqcjJvjTMkXSzWmvAAAAOQGft2pH/wAAJ9en92lJMRsQxu3s9w8CTzKnZ9qySFCfoHTgVnv9ABMw1Vwetzd/YHAT29gXDxVwsQAAAG1Bm7pJqEFsmUwUTCP//eEAAASUtIyG9bHtrQgBbJQPtQKtTi7AeiwGQBW8ctjO7P5U+vRffeOgl7Z5fLZwG1i4GzJ1JZVK6FhDFyYSzrTGujjc/X7u4H8qUewwfpFGTy/RiL59aBbw2M3UwFQgAAAAQAGf2WpH/wAAJ8VT0z1GtBfS3HAu2nL/4I1UmeTw33PKuz1NuKXfii2JQAJ1Sf/q3uvKyJPSat0jziQY7ozdzrAAAABwQZveSeEKUmUwIR/94QAABJNIOnhjGI0MABxupUQRG95IVDrU67e/Y9cAjmSN+z7PLcd9FNZxYjJaZ1bmuvHJ5X+JMG6vNYyW7zDJ+CZX8PMKcxhCDnT3gJQ1mNYvdO/rt5wgAwCcHz1IxhcGbxVnGQAAAD1Bn/xFNEwj/wAAGR/r6LRDNvgCgdXoimH0krhpT5mZMY6U2ACdsnl2Kgrft7UDAFMbwXHAr0QaMZ8UBsWAAAAAMwGeG3RH/wAAJ9tXJia1VlJNh6XbTduv2YQMy7+oASyghVNd+euj7ExUWhyifPrATGD7FwAAAD0Bnh1qR/8AACfFU9M5lK12W4MnKCTr0r3GG8Bn3rZZV4AlidaBoGgAQ1cPiphGM5tNE8c+NxwRxffV5Oy5AAAAbUGaAkmoQWiZTAhH//3hAAAEk0vo6Hd/+uaMMV1xXAbKlImzBAMG+z/gYThCpkCJcGq3imaBci/Asfa2NtWrUeS4NbDZTHhKpI/tlzIwjRSEk867Ltxvogcbi7q7fWuyd1zgZoNWEny+YUDC8wgAAABZQZ4gRREsI/8AABkf7C9TrPsISTnAeNN7dmRahIuTFaAAB8yk1/1ddiIhuKam1MmOKs0rGr9FZauwzv35RsZu8dGW+MosY3dDjpEqXE7kKrs9JrJ92rrC2LEAAAA8AZ5fdEf/AAAn2p0oLvLzMO//8Yb0E4dQXUqF8fkWgS0vgCjocJfcyBZdIzS61P0oAE3tXHVh2n7nHaOXAAAARAGeQWpH/wAAJ8VVyFNwCQ7kREguWk4MH44bNUbqCBJdACWFvngaiyjbDdS0oyKa+QINDiiaWqrC46LFT+UTnquSGRy5AAAAZ0GaRkmoQWyZTAhH//3hAAAEs04VrAVw3huYDt5beb0EXWpkOmpVKenxCLHNMiZMTbckob/tIEgesYlnL28zs1nxB3cezm0CvP0Te1ISC6iTXSB5ja1CB1Wb4QtpCNdqJmJ2CG3HvPsAAABDQZ5kRRUsI/8AABm/Q+jTDfGpiXnseSSH2cqLkWTzDBY8JOfZIISucErtmLbY7wzCwAtWZ9FzIxhnT8znj+2X4DthtAAAADIBnoN0R/8AACj+SYQJjC+bnPM7kcNIea4ATkieGWZqVNlUAeFuHgilea0qbtG0wVAcuAAAAEQBnoVqR/8AACkTHABHmTS6cMfgOkKL2DAsdnYAt6DFCUpRKtWZ6KA0p69I8c3ycECyWw7/23F5ZvBP48tfhbiwDyazTwAAAIhBmopJqEFsmUwIR//94QAABLNOEOfQd95xTrEs8N7sOgcNvfANSkWtv2omcgg6tRsvpLEO6WxHZNeFQk58SjK4gy8i0tfYXdf4/0XweU772tr8B9+cK7zCP7Po7fy5aMhqIec2/0H39yp6ROAGre/fd9Yn2XFmYVKLUjp9n+uxZ8tgo1jO+khQAAAAU0GeqEUVLCP/AAAZv1AVF6SAFeaJt72vGJ3fh+aLBW+2CjpaD/src2yJg4qfJRNE0aykK0YyQcONzg9SlX3SGJXBbeqGXqOpP7l06ohWMcVqEbthAAAAQgGex3RH/wAAKPtXId6xL26LwKLIpWBLuqDI989Ldwt4/QRGrhyysyIBu+2ACY9CYbCJ/g3uvgEu2D/VxDioNG5toAAAADcBnslqR/8AACjkGTJw+n1UC2pIrMP1imhp1QUkYL47P6QP0Tia4aN5pDui/QVS0dcr1FhQwy2PAAAAhkGazkmoQWyZTAhH//3hAAAE24agLqcUpszt6RdI1k1gYwOTOYeCnwz3JfRgCGu+GKE19l2JibP78WSWwz6F/ZM+8tRJpKg4F+iy1JOBHMqBTOU0RRSPZ4Dq5Q0fJjFttiS/uqJI272pAtk9HJth0f5mKjfNGWg8PynM8wQqlWMS+037uuw5AAAANkGe7EUVLCP/AAAaaYK/y9ucJJ/j6pDgqf1tjieNP+uVTFIUEEwDiZ6Bw8K6xVLUoaCBW4yOEQAAAEwBnwt0R/8AACj7WALkPjJr14GIhUXA97l0XgHEjG4cMK+O29sq87iTWM0d0ZnOjBMoNl1VO0sABbmjPRpXL7QvFiZNO+kJBzYYtI49AAAAPgGfDWpH/wAAKhlQXgvw6vGAJKmurYbzIB6Als4Q6R/4nMVTD3JiYtGYE5JRSYWl6ZK+s+0KpWv124tBqWPAAAAAc0GbEkmoQWyZTAhH//3hAAAE1oyNq4BBzfY/gAecncCmgq0zDZQJ8bCbgkXZo1RhhMWUbguviMTqcoG1LMR7Y4QxcSCs3M0TFtbLyWzVcjlPwUD8LDPevpPXOvjS0K9LS8q4dDfMB1u6wPRCcQnZNi3UJKoAAABNQZ8wRRUsI/8AABptfJw8tYpShXiWWqWaiAVUAAA46icOq2y2ccXwPLA1VSOWaE3Vdnvx4iwbSSu/D3KdZFd1ytLBAP/0mG0BrwLucCEAAABJAZ9PdEf/AAAp/55St7tiX+qcMj4VfSBeT71CbKBGmCK9TPJ3cj5KX44n5ACAwZpoG3w3TmHtw/MBnfJuobSckFIZlZdj/s7AgAAAADEBn1FqR/8AACoEGZvUDqKfFmtpjea9seLrTeI+UGM/licFYWwjN2j/sRnVNNJ25VgQAAAAgkGbVkmoQWyZTAhH//3hAAAE1LeXjod326rdI6ALgj4hHlSe6lkdChklCHOV/mNymLdc4OwsckzQ9g+zQz90ldu5HiH/GwzyQDt6KtEBu1801pvWMDfIUjVSgDOV9hmOWp+baF5o6I1OXBt71+ncO7ifu4b/5mRdezcvAcp3WYkT1GEAAAA/QZ90RRUsI/8AABpfdT6cEmiD76CInoyq4YIH1GNzNAC2nAxbBqkASz3spzNOgPmwdprJnM0RgSWlnezZKDhBAAAAUgGfk3RH/wAAKf+eku8HBRLJTVThzhe7iNZp5eyZ7RQ/ckvtXhYSAt/t3zKxdmdh8o58AEr6Db2G3D6tRBL7ybV0TOznes1K+6dha2zCIECcA4UAAABHAZ+Vakf/AAAqBBqNr2+ol2rGrSzAJYo2SnkBoy6p1IUKtKVxo4AIU6FPyZumOeHk5k+DFbq3H5k8eXvGcorF3peloYpjYcAAAABmQZuaSahBbJlMCEf//eEAAAT1kl17OSlR7OfdwdANRanfYQdAAfybktSEilv/DVBQIsACcrtJrvmmFBcfbxtEVynEwqGFju16xOKWjHD/SHaE7S8vTU9gy59PBQ3zIY67Lh7OqNugAAAANEGfuEUVLCP/AAAa/3UdC2GPdl5qcMlPGbDktv+nz30m0UvJCsEE02WrkCCOsRGVlCVorDkAAAA7AZ/XdEf/AAArOpz3k7UzCJONdtM83cNVk8wxVE/OXqooeCaYgjbbkIjksLWny3ZDBxEvYJxGeCdsddwAAAA4AZ/Zakf/AAArJBmXyRwQr7hf98mgS++TmualgLN0eXGwAP4aT7QRJW+rbkSPhGIrdjoE7AJBNdwAAACLQZveSahBbJlMCEf//eEAAAUZk+FizP+OqATSUXKp9wHP7jLe29eNUOpziNsGysnipByzX6viZowRJck71gH4PYRCTzh1fbQBrjgBO0J2h5RI82KNGoJDTy20u9Hi9S8/n2GQXNcESjRfa1ESUZIQ1FEIScX4sIf1rIvcYAiq8Xogs/dyrytW7Xgc5wAAAEVBn/xFFSwj/wAAG6l5GJjAPhq/o2eNzLgcz95AAFVm70szH3oh18P3QHofnIgM0I6bcoal5MLjPSN8NR8BTu3t9u8aIcAAAABFAZ4bdEf/AAArH56goyQB3If1SvhHttI+6rWNR322gQfb5Kf1jsL9kAlPUAKr8NsEQAloagG/ZZ83vErwJEe4Zzi54LuBAAAAOAGeHWpH/wAALFmBkUqY7+UEzlk0mvJSE8pt2d/x0wg62DB9f7DVPfn4HPGuC1H56lXwff6ovh61AAAAk0GaAUmoQWyZTAhH//3hAAAFHaZgTC+4geKkOehyfazRT/Rgz+g8K8Rf7cJwWdkQfwJuig+O/z2w8RM9h25QMBQvUHh/Ec94+BhHvLjxSdozlTx5pDW2y4xH9npAqL4toKdsf3UQO+RwPv+UCTDLUWgtgjlxQpNJaPPFGb8wRfCbRc5IRG4UemP4zk8n3WLzzvDhWgAAADxBnj9FFSwj/wAAG6ibTfUMHWUOuqCaTAKZU2FTr8VxNTOaBSn0LtCCXDbnjZXugkh0oSKWP+1bgT6yjW0AAAA8AZ5Aakf/AAAsQke//TZMzt9qQ9RGkozxNpOBycRrTw3TOggNKHq0UfTA3LtJXOZiZfA5Fn7B3HowlmssAAAAj0GaRUmoQWyZTAhH//3hAAAFPZRpHvAfxd2IJGk/veutAZCoXppN8wxR/ig7QSOejkH5q2ULSnO/JSOLgSpiGGQcgG8hQAkT8mhlHLLxLmDKhZSievp0+IUR9rdsxCnzf+aUDoAnam0xVwp3c3CyRGpx4AZvMtIX7rdOSqsx//g/kDwj82TglGHl2vhqjAvhAAAAQ0GeY0UVLCP/AAAcWG3x2M4mGr6w1BhfA+OasQb2toDch7fIKiJcs+xQK9IaPWHwALd5QE9U8eDkTbcbtDY7XSp7AtsAAABTAZ6CdEf/AAAsP56gqAaSjw/mCPBUKJ0xX+MQQsZXqHrm3Ai5/ZI663hXBThK9QmYNoAE7TKjdVWrItCV5baqenoiKTN/DPWYV4LprT3cm4SYnlgAAABJAZ6Eakf/AAAteVdn8pxPbA1Hw7WnbWvLXLH7ZutoQkFjrOre9viei1bpljo1m6swfUVSOlI3WCcg/3McvixACV0BtQNUtJMm8wAAAGNBmohJqEFsmUwIR//94QAABT2SYOhgZ58K9dwJpj3A0dxx6w8hDGUKJCrCUk4j90t7WUZ5l9sKPKFXfjtrxNM+uAKqvURcYn3Vj8gNyACDmkcUDjLmsDpMbKI/wUQs9SeJOeEAAAA/QZ6mRRUsI/8AABxbIscBqHN/YjMW7wVR0w+5ViZJMwYuhUrspZ9RJETWIGB9NmwtIl+I8QepzBtxZx1TidfgAAAATAGex2pH/wAALUgdfZER9JfrjhM94A4muNaEAj3kD9hhg+sK33pbX7LGOcCw5UegA/eYqRCYT89hYH7Fb1LrMpuM9Pio+Kt5VEU55cEAAACLQZrMSahBbJlMCEf//eEAAAVjMf+SSAWc/BO1P30ODt7OPx/g+zOV4+vimm4L/WNZ4NsXe7e49DUjkN2gkGhFexKJztk4rSUJ1ltz3Jce28yCmnMaPWxBCetCj7ndqDMxrJ3zEBahP+0W8R5WySOwRtCSkLPIGOsvP9gi5QqgLDkkTjLsvvD8SmSklQAAAD9BnupFFSwj/wAAHPyeb4v6+0b95r1ACS1FMN2ou17NWxVs6faQpaiZwvsRA4renuaO83kk/SWYv3YQtTOexN0AAAA4AZ8JdEf/AAAunjKKq+1l9f/gDrtkPVDTwWLKzUPw4gkA9tmPtZQRqOCAE0usjxZ54YmgxoSQsoEAAABKAZ8Lakf/AAAugpyf9Fzom0zdt6fSggpimM9He18347wJBg1g+KP3yuMRWOmMMQAhJ7GD8fE6QeVjSvZn5AmkobTsG6+iftNZnVsAAAB8QZsOSahBbJlMFEwj//3hAAAFZtqZaE0AOiIjH7+idfgLjKtXMB4PgrmPgILXm7fOXbO1WalaQTx5NfS30RXAvxoBfeo0lMMTkd/11pZgCV0zbZb837So/Ju6Qf32lhsweQIR6GHyzDpgNEJC/RLcIsa9YJADJJsgA3yrNQAAADkBny1qR/8AAC6WjpWN6mKhuXponfJfRHjaoxslJGUzWNvW/lGbLEnnnJoMEGqFASfHHsOnl32vpywAAABtQZsxSeEKUmUwIR/94QAABYowmHoP7Saq61RVte9yxiHBjqy70TnxreN011BplaBAALfZxtkUPRYuqwBBoP3BnkLtSi5E+u4wbzKkyenh6OtG6oJdli3YfBLC3RHJWaAErso2cCkzeAF2qfOGsgAAAGBBn09FNEwj/wAAHbbe0x1c8C6LeBNGOXVbh9BEFMYXmuvpSzkalH+CNx6m4nMqYT/qcjnJmft/Zb+8VTMqnjZqbIzD9XRxpyJVTMETCr+/cqn8AliUFjsns9wSqQoqbdEAAABLAZ9wakf/AAAvtxe29mPULigN0tteiIbVyOf9atGJsczYTF/lkU0HXznPv9I0S5UroIgwIwyw0a7XQAPeRKdBcwXc1FCc/w0sp7mnAAAAdkGbc0moQWiZTBTwj/3hAAAFhZBBigCgDG9T770T/xOrFZkkWSqKCKVcLLzbCFHE3gELeeuXCbJ8jNgsVIgFJYJ6QKgFxSCtGZHL4mepO/2tlNuLABgfBn/MqDk6Y6JoM+y+WIgrtSY3W2WXJg83dELeqq0+00gAAAA7AZ+Sakf/AAAvzygYxYEcHYSUFdZpGZSDIyu+lmsv5VvPa/K7oAJ27SHJmgG3b23g1iqxEqnyxaU1xukAAABqQZuWSeEKUmUwIR/94QAABasyAgsY1l0CrxdYXUDBJr8EPCcAFAbWfRcANmic9INeEFx4ran83dwX7l5PcGMpBGzdqaRlYhWLAOb5qbQVEkXUDKzOGd8ZyFzThwQ01UJDGkNX5h91VI43JQAAAE9Bn7RFNEwj/wAAHmb3dHiLsDf28x2lqHTYCBVWOnT8WH5w0u6s/DLAX0L6wS8ndzLYfbOszgBCcpXUdzsN03retmtHzKZG9IDgUUt1Em0xAAAAOAGf1WpH/wAAMQ8oLPhZl9PDvkMi4jCew0kNfyt3iuixrEyQfEa9apBiBYVk4eYy2mep9CDHNejQAAAAd0Gb2UmoQWiZTAhH//3hAAAFzZTzHvAUM1WAcByKDNBHKMXxJWYAZMriT7hw6A5tcuTCA4LtgcR7lwL0znPP0IxaxVId0J452B4bRbaemwpOzq7vXFzDAHqWHjj4vrSREFsZVHxH9S4IYwFrYIPmeTFVkyZvhPOCAAAAWkGf90URLCP/AAAfGIGMtbNAPDVam3NC65Jr8fc5p49nCpx47+Y12RBi1XJ5V4UzoSPucAD267B9bPXQA18UB+YqHjKWtiEfodc4r4tyy3HEpYALnigV4xrDoQAAAEMBnhhqR/8AADJPKCz4WaoCnxfgsnbjAIQxMZKNa03BKHd8817MvCB+Uxj2oS0jbGHB5pC06d+MhhK1QAelxi0PQnoMAAAAXEGaG0moQWyZTBRMI//94QAABc2SYOh3e2O2BxKbD6ftbjEQW38L8FUsS03UwWk9f1X43gg63Z76gFmyaQo+OQBUmY1hBbu7le1Gq7u31FyZ3YXJ+uHebH6Z8MLAAAAAQQGeOmpH/wAAMjeetvZaBEaoLqKB2HWuqXJWHXdb4ZPZHZpLbOe8dYjUPtGlXI9YHZtmmgBYIcFudnINXUbewKnBAAAAZUGaPUnhClJlMFLH//yEAAAXNLyEbP/PZgChpcqaFfx7T8cqBCQzXZ0XhGPfiY4hidj385Ib9oMJwMo5sZOPluhMlD6D/wnasT/iD200jPRBMHUoQXFj0vf3TgLdsn8ze8BvmnbAAAAARQGeXGpH/wAAM3encP9x7h4NEMGV4BPJHu9Y7GgLTW0QYBgZEfgmwi0w6piUC8Y3XIACEk7j7Z/6FGCPvN/x5KF2nYmy4QAAAGFBml5J4Q6JlMCP//yEAAAXNIFBdIYfx++9oBU2ADlXrYDNN+EiUzsjBTWCfDrVFiEU+t0Jn++oX7uGKWkk2jJ/lYjXzrHs2KgTqrK9Z26DdJz83DQ0a2huZTxf6SMs1dlnAAAAcEGaf0nhDyZTAhH//eEAAAX4EkyaWIAUEKKL7HPbib+jcRBmYjrdVaABadP3N7/MEgKWC0nZ6QxwLp0lMYbDUAZZG0608QLSWSkJNTvVrPKQmBDeQH5GeH+6BvZ0UUmhF6dtQJqYHXS7FTrEERoz0pAAAABwQZqBSeEPJlMFETwj//3hAAAGHFNJYEwVUCoP0TmZq3ouDMeiB/1crwpabaiJTWdWd1nPX3U0FPdoPKyLIp2G2ViCEISjZrSf6S/CJ5Yju7cNUJIcgxQNxWyX+f7bO8q5SKQGB4aF4cOYVSeFhCMJwQAAAEkBnqBqR/8AADS3n19nFl6g49n6fyjNYxUJSAFlEtE/FLV/kjxtRhObf5DWE8AnPmoYQANURma/lgwlL/7DvXMbs0LQMqIAmdziAAAAckGapEnhDyZTAhH//eEAAAZF8i0o9aQaAfex+IVAYQ1s0O/6a2S4YPJPrhtaN8MSlCC8Bh02ueqR1oF916fAh/I2Jhl9COzW+4QqaJ5aeVNDHGlisBJbRkD7PwSuhMzRy74vvOWTI2mHZKAhLoqp1CjLwQAAAERBnsJFETwj/wAAIbxu9GvzkNfJG8PHn5opyUdSi9fJ3ThGeTDaum0EmwhRB6DddDrl6sM2ezoPO744sKLEJAyi6HsLgQAAAD0BnuNqR/8AADYSIEmz/i+Grpe6qH8EUlThj4c76CwKKnUE2YnH8eFGesiLcUHGFHT1quWxJOUuZkzvdJeAAAAAQ0Ga50moQWiZTAhH//3hAAAGbFX7NxZx/LDOV3Wt2Go0Ux65CGS2dpeFxAFV6lxRbBK+1N7kWi77zIzzybrH7FpSESUAAAA8QZ8FRREsfwAAN1ItDk4ydi68U6o6lxsjQRaH9aJ3Q2XeYY+XfIHmkKOCAQfuhLDzW/AslAh08Nwj/3PJAAAAPAGfJmpH/wAAN1I7/wt4fzOSwRXUfQC/3AGnBIWPuNYSgIjQXjWRplyoYQkWulYaOLH158S4ULxZ0NADyAAAAFtBmylJqEFsmUwUTCP//eEAAAZsU9Q6GBmPKpfzAARDPQm1J7TMaTHsxNXjnZ4YKFBz/BHp8UarmishPfFkHmMLHY+rDJfOA/B7PUvJBdWHFzzzvYNftlj92lDjAAAAMgGfSGpH/wAANzfL7b2TkDKtu9hdhWlxTHljbaSoSueRUXZyYwphZXDr1fTSkFMTXKEfAAAAWUGbS0nhClJlMFLH//yEAAAZsARy4rY3JNLu/8N+w3iZMmchXHA9fsZFjWWwHOZJSR93JnxvvWXIFZsPQD36Umi3Eqv+FXSu1NXBVVGLg/x6lcESLkcFfuhZAAAAMwGfampH/wAAOLJj14AsXAQ6WixwH/oHAqFewCDS9G1fakP3ObRebJTkRijgOtlCgVKVgQAAAFRBm2xJ4Q6JlMCEf/3hAAAGmRaLh5j+WHUgewF9mlTCqi+YhRkSFRyoAaKsR9dapNohdNyxF7lgN5E4fNn1iOsE/HNzLEEFv2jpuDwPJZYpd591bK0AAABhQZuOSeEPJlMFFTwr//44QAABrz3U5W3viaU33+s2Y+cqodNtr2836rlBjAumMZOgZZUZM7uqaHpQh4h1b3Rot4L1dKDR3zIAJQsA/xLczlJRqFz8mTe7rxSNLlQ2LtdFrwAAAD4Bn61qR/8AADh92uwwIxUpfOUJMojkTe5MTpDBnL8UAJYOzQ5fr65ZBpOz52qNbrlQ5SFO4wYn9paz4+VqoAAAAFJBm69J4Q8mUwIV//44QAABsfUirxshQDm4Q7q9Dxk36v2hY/r0DUCjF8GwwAhSUJZekfxXeRCMDnn6fOvE63fR8ApAPL5a4W6h1nIhmqrlr3UEAAAAM0Gb0knhDyZTAj///IQAAAm3rZN12KgWwiPUpi3jLKNG8ty/XD5cpgovjvVCqd9bmGbfiQAAADZBn/BFETwj/wAADYJn70BXYgOyTED23u33v77anBXgAC60nnAf71MCBcZMbobF8cGxNwqYQ8AAAAAvAZ4Rakf/AAADAxBSEwuknL7IApMd6rl8QABB2HtAjGZNNLD9V6CvjaOrah8TcLYAABVHbW9vdgAAAGxtdmhkAAAAAAAAAAAAAAAAAAAD6AAAHwQAAQAAAQAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAFHF0cmFrAAAAXHRraGQAAAADAAAAAAAAAAAAAAABAAAAAAAAHwQAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAABAAAAAAlgAAAGQAAAAAAAkZWR0cwAAABxlbHN0AAAAAAAAAAEAAB8EAAACAAABAAAAABPpbWRpYQAAACBtZGhkAAAAAAAAAAAAAAAAAAAyAAABjQBVxAAAAAAALWhkbHIAAAAAAAAAAHZpZGUAAAAAAAAAAAAAAABWaWRlb0hhbmRsZXIAAAATlG1pbmYAAAAUdm1oZAAAAAEAAAAAAAAAAAAAACRkaW5mAAAAHGRyZWYAAAAAAAAAAQAAAAx1cmwgAAAAAQAAE1RzdGJsAAAAnHN0c2QAAAAAAAAAAQAAAIxhdmMxAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAlgBkABIAAAASAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGP//AAAANmF2Y0MBZAAf/+EAGWdkAB+s2UCYM+XhAAADAAEAAAMAZA8YMZYBAAZo6+PLIsD9+PgAAAAAGHN0dHMAAAAAAAAAAQAAAY0AAAEAAAAAGHN0c3MAAAAAAAAAAgAAAAEAAAD7AAAMCGN0dHMAAAAAAAABfwAAAAEAAAIAAAAAAQAABQAAAAABAAACAAAAAAEAAAAAAAAAAQAAAQAAAAABAAAFAAAAAAEAAAIAAAAAAQAAAAAAAAABAAABAAAAAAEAAAUAAAAAAQAAAgAAAAABAAAAAAAAAAEAAAEAAAAAAQAABQAAAAABAAACAAAAAAEAAAAAAAAAAQAAAQAAAAABAAAFAAAAAAEAAAIAAAAAAQAAAAAAAAABAAABAAAAAAEAAAIAAAAAAQAABQAAAAABAAACAAAAAAEAAAAAAAAAAQAAAQAAAAABAAAFAAAAAAEAAAIAAAAAAQAAAAAAAAABAAABAAAAAAEAAAUAAAAAAQAAAgAAAAABAAAAAAAAAAEAAAEAAAAAAQAABAAAAAACAAABAAAAAAEAAAUAAAAAAQAAAgAAAAABAAAAAAAAAAEAAAEAAAAAAQAABQAAAAABAAACAAAAAAEAAAAAAAAAAQAAAQAAAAABAAAFAAAAAAEAAAIAAAAAAQAAAAAAAAABAAABAAAAAAEAAAUAAAAAAQAAAgAAAAABAAAAAAAAAAEAAAEAAAAAAQAABQAAAAABAAACAAAAAAEAAAAAAAAAAQAAAQAAAAABAAAEAAAAAAIAAAEAAAAAAQAABQAAAAABAAACAAAAAAEAAAAAAAAAAQAAAQAAAAABAAAFAAAAAAEAAAIAAAAAAQAAAAAAAAABAAABAAAAAAEAAAUAAAAAAQAAAgAAAAABAAAAAAAAAAEAAAEAAAAAAQAAAgAAAAABAAAFAAAAAAEAAAIAAAAAAQAAAAAAAAABAAABAAAAAAEAAAUAAAAAAQAAAgAAAAABAAAAAAAAAAEAAAEAAAAAAQAABQAAAAABAAACAAAAAAEAAAAAAAAAAQAAAQAAAAABAAAFAAAAAAEAAAIAAAAAAQAAAAAAAAABAAABAAAAAAEAAAUAAAAAAQAAAgAAAAABAAAAAAAAAAEAAAEAAAAAAQAABQAAAAABAAACAAAAAAEAAAAAAAAAAQAAAQAAAAABAAAEAAAAAAIAAAEAAAAAAQAABQAAAAABAAACAAAAAAEAAAAAAAAAAQAAAQAAAAABAAAFAAAAAAEAAAIAAAAAAQAAAAAAAAABAAABAAAAAAEAAAUAAAAAAQAAAgAAAAABAAAAAAAAAAEAAAEAAAAAAQAABAAAAAACAAABAAAAAAEAAAUAAAAAAQAAAgAAAAABAAAAAAAAAAEAAAEAAAAAAQAABQAAAAABAAACAAAAAAEAAAAAAAAAAQAAAQAAAAABAAAFAAAAAAEAAAIAAAAAAQAAAAAAAAABAAABAAAAAAEAAAUAAAAAAQAAAgAAAAABAAAAAAAAAAEAAAEAAAAAAQAABQAAAAABAAACAAAAAAEAAAAAAAAAAQAAAQAAAAABAAAFAAAAAAEAAAIAAAAAAQAAAAAAAAABAAABAAAAAAEAAAUAAAAAAQAAAgAAAAABAAAAAAAAAAEAAAEAAAAAAQAABQAAAAABAAACAAAAAAEAAAAAAAAAAQAAAQAAAAABAAAFAAAAAAEAAAIAAAAAAQAAAAAAAAABAAABAAAAAAEAAAUAAAAAAQAAAgAAAAABAAAAAAAAAAEAAAEAAAAAAQAABQAAAAABAAACAAAAAAEAAAAAAAAAAQAAAQAAAAABAAAFAAAAAAEAAAIAAAAAAQAAAAAAAAABAAABAAAAAAEAAAUAAAAAAQAAAgAAAAABAAAAAAAAAAEAAAEAAAAAAQAABQAAAAABAAACAAAAAAEAAAAAAAAAAQAAAQAAAAABAAAFAAAAAAEAAAIAAAAAAQAAAAAAAAABAAABAAAAAAEAAAUAAAAAAQAAAgAAAAABAAAAAAAAAAEAAAEAAAAAAQAABQAAAAABAAACAAAAAAEAAAAAAAAAAQAAAQAAAAABAAAFAAAAAAEAAAIAAAAAAQAAAAAAAAABAAABAAAAAAEAAAUAAAAAAQAAAgAAAAABAAAAAAAAAAEAAAEAAAAAAQAABQAAAAABAAACAAAAAAEAAAAAAAAAAQAAAQAAAAABAAAFAAAAAAEAAAIAAAAAAQAAAAAAAAABAAABAAAAAAEAAAUAAAAAAQAAAgAAAAABAAAAAAAAAAEAAAEAAAAAAQAABQAAAAABAAACAAAAAAEAAAAAAAAAAQAAAQAAAAABAAAFAAAAAAEAAAIAAAAAAQAAAAAAAAABAAABAAAAAAEAAAUAAAAAAQAAAgAAAAABAAAAAAAAAAEAAAEAAAAAAQAABQAAAAABAAACAAAAAAEAAAAAAAAAAQAAAQAAAAABAAAFAAAAAAEAAAIAAAAAAQAAAAAAAAABAAABAAAAAAEAAAUAAAAAAQAAAgAAAAABAAAAAAAAAAEAAAEAAAAAAQAABQAAAAABAAACAAAAAAEAAAAAAAAAAQAAAQAAAAABAAAFAAAAAAEAAAIAAAAAAQAAAAAAAAABAAABAAAAAAEAAAUAAAAAAQAAAgAAAAABAAAAAAAAAAEAAAEAAAAAAQAABQAAAAABAAACAAAAAAEAAAAAAAAAAQAAAQAAAAABAAAFAAAAAAEAAAIAAAAAAQAAAAAAAAABAAABAAAAAAEAAAQAAAAAAgAAAQAAAAABAAACAAAAAAEAAAUAAAAAAQAAAgAAAAABAAAAAAAAAAEAAAEAAAAAAQAABQAAAAABAAACAAAAAAEAAAAAAAAAAQAAAQAAAAABAAAFAAAAAAEAAAIAAAAAAQAAAAAAAAABAAABAAAAAAEAAAUAAAAAAQAAAgAAAAABAAAAAAAAAAEAAAEAAAAAAQAABQAAAAABAAACAAAAAAEAAAAAAAAAAQAAAQAAAAABAAAFAAAAAAEAAAIAAAAAAQAAAAAAAAABAAABAAAAAAEAAAUAAAAAAQAAAgAAAAABAAAAAAAAAAEAAAEAAAAAAQAABQAAAAABAAACAAAAAAEAAAAAAAAAAQAAAQAAAAABAAAFAAAAAAEAAAIAAAAAAQAAAAAAAAABAAABAAAAAAEAAAUAAAAAAQAAAgAAAAABAAAAAAAAAAEAAAEAAAAAAQAABQAAAAABAAACAAAAAAEAAAAAAAAAAQAAAQAAAAABAAAFAAAAAAEAAAIAAAAAAQAAAAAAAAABAAABAAAAAAEAAAUAAAAAAQAAAgAAAAABAAAAAAAAAAEAAAEAAAAAAQAABQAAAAABAAACAAAAAAEAAAAAAAAAAQAAAQAAAAABAAADAAAAAAEAAAEAAAAAAQAABQAAAAABAAACAAAAAAEAAAAAAAAAAQAAAQAAAAABAAAFAAAAAAEAAAIAAAAAAQAAAAAAAAABAAABAAAAAAEAAAUAAAAAAQAAAgAAAAABAAAAAAAAAAEAAAEAAAAAAQAABQAAAAABAAACAAAAAAEAAAAAAAAAAQAAAQAAAAABAAAFAAAAAAEAAAIAAAAAAQAAAAAAAAABAAABAAAAAAEAAAUAAAAAAQAAAgAAAAABAAAAAAAAAAEAAAEAAAAAAQAABQAAAAABAAACAAAAAAEAAAAAAAAAAQAAAQAAAAABAAAFAAAAAAEAAAIAAAAAAQAAAAAAAAABAAABAAAAAAEAAAUAAAAAAQAAAgAAAAABAAAAAAAAAAEAAAEAAAAAAQAABAAAAAACAAABAAAAAAEAAAUAAAAAAQAAAgAAAAABAAAAAAAAAAEAAAEAAAAAAQAABAAAAAACAAABAAAAAAEAAAUAAAAAAQAAAgAAAAABAAAAAAAAAAEAAAEAAAAAAQAAAwAAAAABAAABAAAAAAEAAAQAAAAAAgAAAQAAAAABAAADAAAAAAEAAAEAAAAAAQAABAAAAAACAAABAAAAAAEAAAQAAAAAAgAAAQAAAAABAAADAAAAAAEAAAEAAAAAAQAAAwAAAAABAAABAAAAAAIAAAIAAAAAAQAAAwAAAAABAAABAAAAAAEAAAQAAAAAAgAAAQAAAAABAAAEAAAAAAIAAAEAAAAAAQAAAwAAAAABAAABAAAAAAEAAAMAAAAAAQAAAQAAAAABAAACAAAAAAEAAAMAAAAAAQAAAQAAAAABAAACAAAAAAEAAAQAAAAAAgAAAQAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAY0AAAABAAAGSHN0c3oAAAAAAAAAAAAAAY0AAASnAAAAYwAAADgA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\" type=\"video/mp4\" />\n",
       "                 </video>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Animate learned policy\n",
    "save_dir='./videos/tensorflow/6_1/'\n",
    "env = make_env(env_name)\n",
    "generate_animation(env, agent, save_dir=save_dir)\n",
    "[filepath] = glob.glob(os.path.join(save_dir, '*.mp4'))\n",
    "display_animation(filepath)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#TODO\n",
    "\n",
    "# Try to run this on another environment of your choice from OpenAI Gym\n",
    "# read the accompanying text and try to enahnce the network using various variants\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Summary\n",
    "\n",
    "In this notebook we saw how to train a DQN agent with experience replay and target networks. We can improve this agent with many tricks. As we go along, we will be implementing many of these variants."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
